import openpyxl
import re
import logging
import os
# ロギングの設定
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def analyze_excel(file_path):
"""
指定されたExcelファイルの情報を解析し、使用されている機能の数と件数をシートごとに表示する関数。
Args:
file_path (str): 解析するExcelファイルのパス。
Returns:
dict: 解析結果を格納した辞書。
エラー発生時はNoneを返す。
"""
logging.info(f"解析を開始します: {file_path}")
analysis_result = {}
try:
workbook = openpyxl.load_workbook(file_path)
logging.info("Excelファイルの読み込みが完了しました。")
except FileNotFoundError:
logging.error(f"エラー:ファイルが見つかりません - {file_path}")
return None
except Exception as e:
logging.error(f"エラー:Excelファイルの読み込みに失敗しました - {e}")
return None
# 関数をカウントするための正規表現パターン
function_pattern = re.compile(r"([A-Z]+)\(")
logging.info(f"シート数: {len(workbook.sheetnames)}")
for sheet_name in workbook.sheetnames:
analysis_result[sheet_name] = {'関数': {}}
sheet = workbook[sheet_name]
for row in sheet.iter_rows():
for cell in row:
# セルの数式をチェック
if cell.value and isinstance(cell.value, str) and cell.value.startswith('='):
functions = function_pattern.findall(cell.value)
for func in functions:
func_name = func.upper()
analysis_result[sheet_name]['関数'][func_name] = analysis_result[sheet_name]['関数'].get(func_name, 0) + 1
# VBAの存在をチェック
analysis_result['VBA'] = 1 if workbook.vba_archive else 0
logging.info(f"VBAプロジェクトを検出しました。") if workbook.vba_archive else logging.info("VBAプロジェクトは検出されませんでした。")
# マクロの存在をチェック
try:
if hasattr(workbook, 'macros') and workbook.macros:
analysis_result['マクロ'] = len(workbook.macros)
logging.info(f"マクロを検出しました - {len(workbook.macros)}個")
else:
analysis_result['マクロ'] = 0
logging.info("マクロは検出されませんでした。")
except AttributeError:
logging.warning(f" ワークブックにマクロ属性がありません。")
analysis_result['マクロ'] = 0
workbook.close()
logging.info("解析が完了しました。")
return analysis_result
def display_analysis_result(result, output_excel=False):
"""
解析結果を見やすく表示する関数。
Args:
result (dict): 解析結果を格納した辞書。
output_excel (bool, optional): 結果をExcelファイルに出力するかどうか。デフォルトはFalse。
"""
if result is None:
print("解析に失敗しました。ログを確認してください。")
return
print("\nExcelファイル解析結果:")
print("------------------------")
for sheet_name, sheet_result in result.items():
if sheet_name in ['VBA', 'マクロ']: # VBAとマクロはシートごとではないのでスキップ
continue
print(f"\nシート名: {sheet_name}")
print("------------------------")
print("関数:")
if sheet_result.get('関数'): # シートに'関数'キーが存在するか確認
for func, count in sheet_result['関数'].items():
print(f" {func}: {count}個")
else:
print(" 使用されている関数はありません")
print(f"VBA:{'あり' if result.get('VBA', 0) else 'なし'}") # resultに'VBA'キーが存在するか確認
print(f"マクロ:{result.get('マクロ', 0)}個") # resultに'マクロ'キーが存在するか確認
print("------------------------")
if output_excel:
output_wb = openpyxl.Workbook()
for sheet_name, sheet_result in result.items():
if sheet_name in ['VBA', 'マクロ']: # VBAとマクロはシートごとではないのでスキップ
continue
output_sheet = output_wb.create_sheet(title=sheet_name)
headers = ["項目", "種類", "個数"]
output_sheet.append(headers)
if sheet_result.get('関数'): # シートに'関数'キーが存在するか確認
for func, count in sheet_result['関数'].items():
output_sheet.append(["関数", func, count])
else:
output_sheet.append(["関数", "使用なし", 0])
# VBAとマクロの結果を最初のシートに追記
if 'Sheet' in output_wb.sheetnames:
output_sheet = output_wb['Sheet']
else:
output_sheet = output_wb.active
output_sheet.append(["VBA", "", "あり" if result.get('VBA', 0) else "なし"]) # resultに'VBA'キーが存在するか確認
output_sheet.append(["マクロ", "", result.get('マクロ', 0)]) # resultに'マクロ'キーが存在するか確認
output_file_name = "excel_analysis_result.xlsx"
try:
output_wb.save(output_file_name)
print(f"解析結果をExcelファイルに保存しました: {output_file_name}")
except Exception as e:
print(f"エラー:Excelファイルへの保存に失敗しました - {e}")
if __name__ == "__main__":
# Google Colab環境かどうかを判定
try:
from google.colab import files
# ファイルアップロードダイアログを表示
uploaded = files.upload()
if uploaded:
# アップロードされた最初のファイルのパスを取得
file_path = list(uploaded.keys())[0]
logging.info(f"アップロードされたファイル: {file_path}")
else:
logging.error("ファイルがアップロードされませんでした。")
print("エラー:ファイルがアップロードされませんでした。")
exit()
except ImportError:
# Google Colab環境でない場合は、ローカルファイルのパスを入力
file_path = input("解析するExcelファイルのパスを入力してください: ")
if not os.path.exists(file_path):
print(f"エラー:指定されたパスにファイルが存在しません: {file_path}")
exit() # プログラムを終了する
analysis_result = analyze_excel(file_path)
if analysis_result:
display_analysis_result(analysis_result, output_excel=True)
【DX推進の落とし穴?】中小企業のExcel活用と隠れた課題に迫る!

この記事は約10分で読めます。
12
コメント