概要

高度なGoogle Sheetsツールは、完全なシートデータを取得する機能を含む、Google Sheetsとの強化された統合機能を提供します。これは、包括的なデータアクセスのための追加機能で、既存のGoogle SheetsとGoogle Spreadsheetツールを補完します。

主な機能

GOOGLE_SHEETS_GET_SHEET

  • Google Sheetsから完全なシートデータを取得
  • すべてのセルとフォーマット情報へのアクセス
  • ワークブック内の複数シートをサポート
  • 大規模データセットの効率的なデータ取得

認証

Google Sheets統合には、Google API資格情報と適切な権限が必要です。 必要なセットアップ:
  1. Sheets APIが有効化されたGoogle Cloud Consoleプロジェクト
  2. サービスアカウント資格情報またはOAuth 2.0クライアント
  3. 対象シートでの適切な共有権限
注意: API資格情報は機密情報として扱い、パブリックリポジトリにコミットしないでください。

例: 完全なシートデータ取得

- id: get_full_sheet_data
  name: get_full_sheet_data
  tool: GOOGLE_SHEETS_GET_SHEET
  config:
    - name: credentials
      value: "{{secrets.GOOGLE_SHEETS_CREDENTIALS}}"
  input:
    - name: sheet_id
      value: "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms"
    - name: sheet_name
      value: "Sheet1"  # オプション: デフォルトは最初のシート
    - name: include_formatting
      value: true
    - name: include_metadata
      value: true

- id: analyze_sheet_structure
  name: analyze_sheet_structure
  tool: PYTHON_SANDBOX_RUN
  input:
    - name: code
      value: |
        import json
        
        # 取得したシートデータを分析
        sheet_data = json.loads('''{{steps.get_full_sheet_data.result.sheet_data}}''')
        
        print("Google Sheet分析")
        print("=" * 20)
        
        # 基本情報
        print(f"シート名: {sheet_data.get('sheet_name', '不明')}")
        print(f"シートID: {sheet_data.get('sheet_id', '不明')}")
        
        # データ次元
        rows = sheet_data.get('rows', [])
        if rows:
            max_cols = max(len(row) for row in rows)
            print(f"サイズ: {len(rows)}行 × {max_cols}列")
            
            # データプレビュー
            print("\nデータプレビュー(最初の5行):")
            for i, row in enumerate(rows[:5], 1):
                print(f"行{i}: {row[:5]}...")  # 最初の5列を表示
        else:
            print("シートにデータが見つかりません")
        
        # メタデータ
        if 'metadata' in sheet_data:
            metadata = sheet_data['metadata']
            print(f"\nメタデータ:")
            print(f"  最終更新: {metadata.get('modified_time', '不明')}")
            print(f"  所有者: {metadata.get('owner', '不明')}")

- id: convert_to_structured_format
  name: convert_to_structured_format
  tool: PYTHON_SANDBOX_RUN
  input:
    - name: code
      value: |
        import json
        
        sheet_data = json.loads('''{{steps.get_full_sheet_data.result.sheet_data}}''')
        rows = sheet_data.get('rows', [])
        
        if not rows:
            print("変換するデータがありません")
        else:
            # 最初の行にヘッダーがあると仮定
            headers = rows[0] if rows else []
            data_rows = rows[1:] if len(rows) > 1 else []
            
            # オブジェクトの配列に変換
            structured_data = []
            for row in data_rows:
                row_obj = {}
                for i, header in enumerate(headers):
                    value = row[i] if i < len(row) else ""
                    row_obj[header] = value
                structured_data.append(row_obj)
            
            # 構造化データを出力
            result = {
                "headers": headers,
                "data": structured_data,
                "record_count": len(structured_data)
            }
            
            print(json.dumps(result, indent=2, ensure_ascii=False))

- id: export_structured_data
  name: export_structured_data
  tool: OUTPUT_FILE
  input:
    - name: content
      value: "{{steps.convert_to_structured_format.result.stdout}}"
    - name: filename
      value: "google_sheets_export_{{date | format('YYYY-MM-DD')}}.json"
    - name: fileType
      value: "json"

例: マルチシートワークブック処理

- id: get_workbook_info
  name: get_workbook_info
  tool: GOOGLE_SHEETS_GET_SHEET
  config:
    - name: credentials
      value: "{{secrets.GOOGLE_SHEETS_CREDENTIALS}}"
  input:
    - name: sheet_id
      value: "{{input.workbook_id}}"
    - name: get_sheet_list
      value: true  # ワークブック内のすべてのシートのリストを取得

- id: process_all_sheets
  name: process_all_sheets
  tool: PYTHON_SANDBOX_RUN
  input:
    - name: code
      value: |
        import json
        
        # ワークブックからシートリストを取得
        workbook_info = json.loads('''{{steps.get_workbook_info.result.workbook_info}}''')
        sheets = workbook_info.get('sheets', [])
        
        print("マルチシート処理計画")
        print("=" * 25)
        print(f"ワークブックID: {workbook_info.get('workbook_id', '不明')}")
        print(f"総シート数: {len(sheets)}")
        print("\n処理するシート:")
        
        processing_plan = []
        for i, sheet in enumerate(sheets):
            sheet_name = sheet.get('name', f'Sheet{i+1}')
            sheet_info = {
                "sheet_name": sheet_name,
                "step_id": f"get_sheet_{i+1}",
                "processing_order": i+1
            }
            processing_plan.append(sheet_info)
            print(f"  {i+1}. {sheet_name}")
        
        print(f"\n{len(processing_plan)}シートの処理計画を作成しました")
        print(json.dumps(processing_plan, indent=2, ensure_ascii=False))

- id: get_sales_sheet
  name: get_sales_sheet
  tool: GOOGLE_SHEETS_GET_SHEET
  config:
    - name: credentials
      value: "{{secrets.GOOGLE_SHEETS_CREDENTIALS}}"
  input:
    - name: sheet_id
      value: "{{input.workbook_id}}"
    - name: sheet_name
      value: "Sales Data"
    - name: include_formatting
      value: true

- id: get_inventory_sheet
  name: get_inventory_sheet
  tool: GOOGLE_SHEETS_GET_SHEET
  config:
    - name: credentials
      value: "{{secrets.GOOGLE_SHEETS_CREDENTIALS}}"
  input:
    - name: sheet_id
      value: "{{input.workbook_id}}"
    - name: sheet_name
      value: "Inventory"
    - name: include_formatting
      value: true

- id: consolidate_workbook_data
  name: consolidate_workbook_data
  tool: PYTHON_SANDBOX_RUN
  input:
    - name: code
      value: |
        import json
        from datetime import datetime
        
        # 複数シートからデータを統合
        sales_data = json.loads('''{{steps.get_sales_sheet.result.sheet_data}}''')
        inventory_data = json.loads('''{{steps.get_inventory_sheet.result.sheet_data}}''')
        
        consolidated_report = {
            "report_date": datetime.now().isoformat(),
            "workbook_id": "{{input.workbook_id}}",
            "sheets_processed": [],
            "summary_statistics": {},
            "data_quality_checks": []
        }
        
        # 売上データを処理
        if sales_data.get('rows'):
            sales_rows = len(sales_data['rows']) - 1  # ヘッダーを除く
            consolidated_report["sheets_processed"].append({
                "sheet_name": "Sales Data",
                "row_count": sales_rows,
                "status": "processed"
            })
        
        # 在庫データを処理
        if inventory_data.get('rows'):
            inventory_rows = len(inventory_data['rows']) - 1  # ヘッダーを除く
            consolidated_report["sheets_processed"].append({
                "sheet_name": "Inventory",
                "row_count": inventory_rows,
                "status": "processed"
            })
        
        # サマリー統計を計算
        total_rows = sum(sheet["row_count"] for sheet in consolidated_report["sheets_processed"])
        consolidated_report["summary_statistics"] = {
            "total_data_rows": total_rows,
            "sheets_processed": len(consolidated_report["sheets_processed"]),
            "processing_time": "{{date | format('HH:mm:ss')}}"
        }
        
        print("ワークブック統合完了")
        print("=" * 20)
        print(json.dumps(consolidated_report, indent=2, ensure_ascii=False))

- id: save_consolidated_report
  name: save_consolidated_report
  tool: OUTPUT_FILE
  input:
    - name: content
      value: "{{steps.consolidate_workbook_data.result.stdout}}"
    - name: filename
      value: "workbook_consolidation_report.json"
    - name: fileType
      value: "json"

例: データ品質分析

- id: retrieve_data_for_analysis
  name: retrieve_data_for_analysis
  tool: GOOGLE_SHEETS_GET_SHEET
  config:
    - name: credentials
      value: "{{secrets.GOOGLE_SHEETS_CREDENTIALS}}"
  input:
    - name: sheet_id
      value: "{{input.analysis_sheet_id}}"
    - name: sheet_name
      value: "{{input.sheet_name}}"
    - name: include_formatting
      value: true
    - name: include_metadata
      value: true

- id: perform_data_quality_analysis
  name: perform_data_quality_analysis
  tool: PYTHON_SANDBOX_RUN
  input:
    - name: code
      value: |
        import json
        import re
        from collections import Counter
        
        # データ品質を分析
        sheet_data = json.loads('''{{steps.retrieve_data_for_analysis.result.sheet_data}}''')
        rows = sheet_data.get('rows', [])
        
        if not rows:
            print("分析するデータが見つかりません")
        else:
            headers = rows[0] if rows else []
            data_rows = rows[1:] if len(rows) > 1 else []
            
            print("データ品質分析レポート")
            print("=" * 25)
            print(f"データセット: {sheet_data.get('sheet_name', '不明')}")
            print(f"総レコード数: {len(data_rows)}")
            print(f"総列数: {len(headers)}")
            print()
            
            # 列ごとの分析
            quality_report = {
                "overall_stats": {
                    "total_records": len(data_rows),
                    "total_columns": len(headers),
                    "completeness_score": 0
                },
                "column_analysis": [],
                "data_issues": []
            }
            
            total_cells = 0
            empty_cells = 0
            
            for col_idx, header in enumerate(headers):
                col_values = [row[col_idx] if col_idx < len(row) else "" for row in data_rows]
                
                # 列統計を計算
                non_empty_values = [v for v in col_values if str(v).strip()]
                empty_count = len(col_values) - len(non_empty_values)
                completeness = (len(non_empty_values) / len(col_values)) * 100 if col_values else 0
                
                # データ型検出
                numeric_count = sum(1 for v in non_empty_values if str(v).replace('.', '').replace('-', '').isdigit())
                date_count = sum(1 for v in non_empty_values if re.match(r'\d{1,2}[/-]\d{1,2}[/-]\d{2,4}', str(v)))
                email_count = sum(1 for v in non_empty_values if '@' in str(v) and '.' in str(v))
                
                likely_type = "テキスト"
                if numeric_count / len(non_empty_values) > 0.8 if non_empty_values else False:
                    likely_type = "数値"
                elif date_count / len(non_empty_values) > 0.5 if non_empty_values else False:
                    likely_type = "日付"
                elif email_count / len(non_empty_values) > 0.5 if non_empty_values else False:
                    likely_type = "メール"
                
                col_analysis = {
                    "column_name": header,
                    "completeness_percent": round(completeness, 2),
                    "empty_cells": empty_count,
                    "likely_data_type": likely_type,
                    "unique_values": len(set(non_empty_values)),
                    "sample_values": non_empty_values[:3]
                }
                
                quality_report["column_analysis"].append(col_analysis)
                
                total_cells += len(col_values)
                empty_cells += empty_count
                
                # 潜在的な問題を特定
                if completeness < 90:
                    quality_report["data_issues"].append(f"列'{header}'の完全性が低い({completeness:.1f}%)")
                
                if len(set(non_empty_values)) == 1 and non_empty_values:
                    quality_report["data_issues"].append(f"列'{header}'には1つの一意の値しかない")
            
            # 全体の完全性スコア
            overall_completeness = ((total_cells - empty_cells) / total_cells) * 100 if total_cells > 0 else 0
            quality_report["overall_stats"]["completeness_score"] = round(overall_completeness, 2)
            
            print(f"全体データ完全性: {overall_completeness:.1f}%")
            print()
            
            # 列分析を表示
            print("列分析:")
            for col in quality_report["column_analysis"]:
                print(f"  📊 {col['column_name']}")
                print(f"     完全性: {col['completeness_percent']}%")
                print(f"     型: {col['likely_data_type']}")
                print(f"     一意の値: {col['unique_values']}")
                print()
            
            # 問題を表示
            if quality_report["data_issues"]:
                print("🚨 データ品質の問題:")
                for issue in quality_report["data_issues"]:
                    print(f"  - {issue}")
            else:
                print("✅ 主要なデータ品質の問題は検出されませんでした")
            
            print("\n" + json.dumps(quality_report, indent=2, ensure_ascii=False))

- id: create_quality_recommendations
  name: create_quality_recommendations
  tool: OPENAI_INVOKE
  config:
    - name: version
      value: gpt-4
  input:
    - name: prompt
      value: |
        このデータ品質分析レポートに基づいて、データ品質向上のための具体的な推奨事項を提供してください:
        
        {{steps.perform_data_quality_analysis.result.stdout}}
        
        以下を提供してください:
        1. 最初に対処すべき優先度の高い問題
        2. データ完全性を改善するための具体的なステップ
        3. 実装すべきデータ検証ルール
        4. 継続的なデータメンテナンスのベストプラクティス
        5. 推奨されるデータクリーニングワークフロー

- id: save_quality_analysis_report
  name: save_quality_analysis_report
  tool: OUTPUT_FILE
  input:
    - name: content
      value: |
        Google Sheetsデータ品質分析レポート
        ==================================
        
        生成日時: {{date | format('YYYY-MM-DD HH:mm:ss')}}
        
        ## 分析結果
        {{steps.perform_data_quality_analysis.result.stdout}}
        
        ## 推奨事項
        {{steps.create_quality_recommendations.result.content}}
        
        ## 次のステップ
        1. 高優先度のデータ品質問題に対処
        2. 推奨されるデータ検証ルールを実装
        3. 定期的なデータ品質監視を設定
        4. データ入力のベストプラクティスをユーザーに研修
        5. 自動データクリーニングワークフローを検討
    - name: filename
      value: "data_quality_analysis_{{date | format('YYYY-MM-DD')}}.txt"
    - name: fileType
      value: "txt"

シート取得オプション

基本取得

  • sheet_id: Google SheetsドキュメントID
  • sheet_name: 特定のシートタブ名(オプション)
  • range: 特定のセル範囲(オプション)

高度なオプション

  • include_formatting: セルフォーマット情報を含む
  • include_metadata: シートメタデータ(所有者、更新日など)を含む
  • get_sheet_list: ワークブック内のすべてのシートのリストを取得
  • preserve_empty_cells: 出力に空のセルを含む

データフォーマット

標準レスポンス

{
  "sheet_id": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
  "sheet_name": "Sheet1",
  "rows": [
    ["ヘッダー1", "ヘッダー2", "ヘッダー3"],
    ["値1", "値2", "値3"],
    ["値4", "値5", "値6"]
  ],
  "metadata": {
    "modified_time": "2024-01-15T10:30:00Z",
    "owner": "user@example.com"
  }
}

フォーマット付き

{
  "sheet_data": {
    "rows": [...],
    "formatting": {
      "cell_formats": {
        "A1": {"bold": true, "background_color": "#ffff00"},
        "B1": {"italic": true, "text_color": "#ff0000"}
      }
    }
  }
}

使用例

  • データ分析: 分析用の完全なデータセットを取得
  • レポート作成: Google Sheetsデータからレポートを生成
  • データ移行: Google Sheetsから他のシステムにデータをエクスポート
  • 品質保証: データ品質と完全性を分析
  • バックアップとアーカイブ: 重要なスプレッドシートのバックアップを作成
  • 統合: Google Sheetsデータを他のワークフローツールに接続
  • ダッシュボード作成: ダッシュボードと可視化ツール用のデータを取得
  • コンプライアンスレポート: 規制レポート用のデータを抽出

ベストプラクティス

パフォーマンス最適化

  • 必要なデータ範囲のみを取得
  • 適切な包含オプション(フォーマット、メタデータ)を使用
  • 非常に大きなシートでのページネーションを検討
  • 頻繁にアクセスするデータをキャッシュ

データ処理

  • 取得したデータ構造を常に検証
  • 空のセルと欠損データを適切に処理
  • アクセス権限の問題に対するエラー処理を実装
  • データプライバシーとセキュリティ要件を考慮

統合戦略

  • 下流処理用の構造化データフォーマットを使用
  • 取得後にデータ品質チェックを実装
  • 監査証跡のためにデータ取得操作を記録
  • レート制限とクォータ管理を計画