🤖

ChatGPTに伝わらないモヤモヤを解決するMarkdownTable生成VBAマクロ

2023/05/07に公開

1.Markdownテーブルで正確にExcelセル情報を伝えよう

ExcelについてChatGPTに質問する際、セルの内容を説明するのが面倒ですよね?
「A列にはXXXという情報があって~」などと伝えるのは煩わしいですし、Excel表をコピペしても、正確にChatGPTにセル情報が伝わらないことがあります。

そんなときには、Markdown記法のテーブルを使ってみましょう!Markdown形式のテーブルを使うことで、セル情報を正確にChatGPTに伝えることができます。

↓こんな感じのマクロです。

2.はじめに

そもそもMarkdownテーブルって何?

基本

Markdownテーブルは、Markdown形式で記述された表(table)のことです。Markdownは、マークアップ言語であり、HTMLやTeXのような言語よりも直感的に書くことができます。Markdownテーブルは、シンプルな形式で表を作成できるため、GitHubやZenn、Qiita、Notionなどで広く利用されています。

Markdownテーブルの基本的な構造は、以下のようになります。

記載するMarkdownテーブル 1
| ヘッダー1 | ヘッダー2 | ヘッダー3 |
|---|---|---|
| セル1-1   | セル1-2   | セル1-3   |
| セル2-1   | セル2-2   | セル2-3   |

↓表示されるMarkdownテーブル

ヘッダー1 ヘッダー2 ヘッダー3
セル1-1 セル1-2 セル1-3
セル2-1 セル2-2 セル2-3

具体例

具体的にExcelが画像のようなセル状態になっているとします。これをMarkdownテーブルで表現すると以下のようになります。
※名前はダミー情報です。

記載するMarkdownテーブル 2
| ↓行 / 列→ | B | C | D | E |
|---|---|---|---|---|
|9|ID|フルネーム|||
|10|K34a3|下村 愛作|||
|11|K34a4|辻 秋美|||
|12|K34a5|長沢 百世|||
|13|K34a6|藤村 君吉|||
|14|K34a7|沢田 優紀|||
↓行 / 列→ B C D E
9 ID フルネーム
10 K34a3 下村 愛作
11 K34a4 辻 秋美
12 K34a5 長沢 百世
13 K34a6 藤村 君吉
14 K34a7 沢田 優紀

VBAコードの目的

本VBAコードの目的は、Excel業務でChatGPTに質問する際、Markdown形式でExcelのセル状態を伝えることで、ChatGPTの回答精度を向上させることです。このコードは、Excelのセル範囲を選択して、それをMarkdown形式のテーブルとしてクリップボードにコピーする機能を提供します。

Excelの状態が伝わりやすいプロンプト
Excelシート「Sheet1」のセル状態 : """
| ↓行 / 列→ | B | C | D | E |
|---|---|---|---|---|
|9|ID|フルネーム|||
|10|K34a3|下村 愛作|||
|11|K34a4|辻 秋美|||
|12|K34a5|長沢 百世|||
|13|K34a6|藤村 君吉|||
|14|K34a7|沢田 優紀|||
"""
単にExcelからコピペしたプロンプト
Excelシート「Sheet1」のセル状態 : """
ID	フルネーム	姓	名
K34a3	下村 愛作		
K34a4	辻 秋美		
K34a5	長沢 百世		
K34a6	藤村 君吉		
K34a7	沢田 優紀		
"""

VBAコードの利点

このVBAコードの利点は以下の通りです。

  1. Excelのセル範囲を簡単にMarkdown形式のテーブルに変換できる。
  2. クリップボードにコピーされるため、他のアプリケーションで簡単に使用できる。
  3. ChatGPTに質問する際の情報伝達が効率化され、回答精度が向上する。

またセル情報の他、シート名を含んだプロンプトがクリップボードにコピーされるので便利だと思います。プロンプトは「日本語で解説!Best practices for prompt engineering with OpenAI API」に従った形でコピーされます。

https://zenn.dev/milo/articles/c8a29d4a434bc3

3.使用方法の概要

マクロの準備

試した環境

  1. Windows11/10
  2. Microsoft Excel 365/2019

以下のURLより完成品をダウンロードしてください

Dropboxの登録ウィンドウが出ますが、登録しないでもダウンロードできます。

https://www.dropbox.com/s/c1v4m832cytnfgy/ChatGPT_CreateMDT.zip?dl=0

ダウンロードしたExcelについて、セキュリティの許可をする

  1. Excelを右クリック
  2. 「プロパティ」をクリック
  3. 「セキュリティ」>「許可する」のチェックを入れる
  4. 「OK」をクリック
    WebからダウンロードしたExcelマクロは以下の設定をしないとマクロが動きません。

マクロの使用方法

Excelシートには3つのマクロボタンが用意してあります。
「MDテーブル作成_シンプル」「MDテーブル作成_行と列」「MDテーブル作成_ABC」

  1. 3つのうちいずれかを押下してマクロを実行します。
  2. ユーザーにセル範囲を選択してもらいます。
  3. 選択されたセル範囲をMarkdown形式のテーブルに変換し、クリップボードにコピーします。

4.それぞれのボタンの違い

試しに画像のような「B2からE6のセル範囲(B2:E6)」を選択したとします。

以下、「MDテーブル作成_シンプル」「MDテーブル作成_行と列」「MDテーブル作成_ABC」それぞれでどのような内容がクリップボードに格納されるかを説明します。
※ChatGPTに聞きたいシチュエーションに合わせてご利用ください。

「MDテーブル作成_シンプル」

シンプルなMarkdownテーブルを作成するマクロです。
これは、他のWebサービスでも同じようなもの(Excel表をコピペするとMarkdownテーブルに変換してくれるサービス)があるので馴染み深いと思います。
※Excelに関する質問以外で表情報をChatGPTに伝えたいときにおすすめです。

「MDテーブル作成_行と列」 ★★★★★おすすめ

ChatGPTに行と列の情報を伝えることができます。
行と列の情報を伝えることができるので、ChatGPTからもらった回答(Excel関数やExcelVBA)をそのまま利用できる可能性が高まります。

「MDテーブル作成_ABC」

ChatGPTに列の情報を伝えることができます。
※行の情報まではいらない場合(プロンプトの文字数を削減したい場合)などにご利用ください。

5.VBAコード

下記アコーディオンをクリックすると、コードを閲覧できます。

宣言セクション
VBA
Option Explicit
Sub createMarkdownTableStr_simple()
VBA
Sub createMarkdownTableStr_simple()
    Dim mdtStr As String ' Markdown Table String
    Dim rng As Range
    Dim selectedRange As Range

    ' ユーザーにセル範囲を選択してもらう
    On Error Resume Next
    Set selectedRange = Application.InputBox("セルを選択してください", Type:=8)
    On Error GoTo 0
    
    If selectedRange Is Nothing Then
        MsgBox "選択がキャンセルされました"
        Exit Sub
    End If
    
    ' セル範囲からシートを特定する
    Dim ws As Worksheet
    Set ws = selectedRange.Parent
    ws.Activate
    
    ' 選択範囲の列数を取得
    Dim columnCount As Integer
    columnCount = selectedRange.Columns.Count
    
    ' 判定に使用する行数と列数を取得
    Dim firstRow As Integer
    Dim firstColumn As Integer
    Dim lastColumn As Integer
    firstRow = selectedRange.row
    firstColumn = selectedRange.Column
    lastColumn = firstColumn + columnCount - 1
    
    ' カラムヘッダー行を作成
    mdtStr = "|"
    For Each rng In selectedRange
        If firstRow = rng.row Then
            mdtStr = mdtStr & rng.Value & "|"
        End If
    Next
    mdtStr = mdtStr & vbCrLf & "|"
    
    ' ヘッダー行とデータ行の区切りを作成
    Dim i As Long
    For i = 1 To columnCount
        mdtStr = mdtStr & "---|"
    Next
    mdtStr = mdtStr & vbCrLf & "|"

    ' データ行を作成
    For Each rng In selectedRange
        If firstRow <> rng.row Then ' 1行以外のもの
            If lastColumn = rng.Column Then ' 列が最終のものであるか否かで、vbCrLfを付けるかつけないか決める。
                mdtStr = mdtStr & rng.Value & "|" & vbCrLf & "|"
            Else
                mdtStr = mdtStr & rng.Value & "|"
            End If
        End If
    Next
    Dim a As Worksheet
    ' 右1文字を削除する
    mdtStr = Left(mdtStr, Len(mdtStr) - 1)
    
    ' シート名とMarkdownTableでプロンプトを作る
    Dim promptStr As String
    promptStr = "Excelシート「" & ws.Name & "」のセル状態 : """"""" & vbCrLf
    promptStr = promptStr & mdtStr
    promptStr = promptStr & """"""""
    
    Call strToClipboard(promptStr)
End Sub
Sub createMarkdownTableStr_RowCol()
VBA
Sub createMarkdownTableStr_RowCol()
    Dim mdtStr As String ' Markdown Table String
    Dim rng As Range
    Dim selectedRange As Range

    ' ユーザーにセル範囲を選択してもらう
    On Error Resume Next
    Set selectedRange = Application.InputBox("セルを選択してください", Type:=8)
    On Error GoTo 0

    If selectedRange Is Nothing Then
        MsgBox "選択がキャンセルされました"
        Exit Sub
    End If

    ' セル範囲からシートを特定する
    Dim ws As Worksheet
    Set ws = selectedRange.Parent
    ws.Activate
    

    ' 選択範囲の行数と列数を取得
    Dim columnCount As Long
    Dim rowCount As Long
    columnCount = selectedRange.Columns.Count
    rowCount = selectedRange.Rows.Count

    ' 判定に使用する行数と列数を取得
    Dim firstRow As Integer
    Dim firstColumn As Integer
    Dim lastRow As Integer
    Dim lastColumn As Integer
    firstRow = selectedRange.row
    firstColumn = selectedRange.Column
    lastRow = firstRow + rowCount - 1
    lastColumn = firstColumn + columnCount - 1

    ' カラムヘッダー行を作成
    Dim col As Long
    mdtStr = "| ↓行 / 列→"
    For col = firstColumn To lastColumn
        mdtStr = mdtStr & " | " & Split(Cells(, col).Address, "$")(1)
    Next col
    mdtStr = mdtStr & " |" & vbCrLf

    ' ヘッダー行とデータ行の区切りを作成
    Dim i As Long
    mdtStr = mdtStr & "|---"
    For i = 1 To columnCount
        mdtStr = mdtStr & "|---"
    Next
    mdtStr = mdtStr & "|" & vbCrLf

    ' データ行を作成
    Dim row As Long
    For row = firstRow To lastRow
        mdtStr = mdtStr & "|" & row
        For col = firstColumn To lastColumn
            mdtStr = mdtStr & "|" & Cells(row, col).Value
        Next col
        mdtStr = mdtStr & "|" & vbCrLf
    Next row

    ' シート名とMarkdownTableでプロンプトを作る
    Dim promptStr As String
    promptStr = "Excelシート「" & ws.Name & "」のセル状態 : """"""" & vbCrLf
    promptStr = promptStr & mdtStr
    promptStr = promptStr & """"""""
    
    Call strToClipboard(promptStr)
End Sub

Sub createMarkdownTableStr_ABC()
VBA
Sub createMarkdownTableStr_ABC()
    Dim mdtStr As String ' Markdown Table String
    Dim rng As Range
    Dim selectedRange As Range

    ' ユーザーにセル範囲を選択してもらう
    On Error Resume Next
    Set selectedRange = Application.InputBox("セルを選択してください", Type:=8)
    On Error GoTo 0
    
    If selectedRange Is Nothing Then
        MsgBox "選択がキャンセルされました"
        Exit Sub
    End If
    
    ' セル範囲からシートを特定する
    Dim ws As Worksheet
    Set ws = selectedRange.Parent
    ws.Activate
    
    ' 選択範囲の列数を取得
    Dim columnCount As Integer
    columnCount = selectedRange.Columns.Count
    
    ' 判定に使用する行数と列数を取得
    Dim firstRow As Integer
    Dim firstColumn As Integer
    Dim lastColumn As Integer
    firstRow = selectedRange.row
    firstColumn = selectedRange.Column
    lastColumn = firstColumn + columnCount - 1
    
    ' カラムヘッダー行を作成
    mdtStr = "|"
    For Each rng In selectedRange
        If firstRow = rng.row Then
            mdtStr = mdtStr & getColName(rng.Column) & "|"
        End If
    Next
    mdtStr = mdtStr & vbCrLf & "|"
    
    ' ヘッダー行とデータ行の区切りを作成
    Dim i As Long
    For i = 1 To columnCount
        mdtStr = mdtStr & "---|"
    Next
    mdtStr = mdtStr & vbCrLf & "|"

    ' データ行を作成
    For Each rng In selectedRange
        If lastColumn = rng.Column Then ' 列が最終のものであるか否かで、vbCrLfを付けるかつけないか決める。
            mdtStr = mdtStr & rng.Value & "|" & vbCrLf & "|"
        Else
            mdtStr = mdtStr & rng.Value & "|"
        End If
    Next
    
    Dim a As Worksheet
    ' 右1文字を削除する
    mdtStr = Left(mdtStr, Len(mdtStr) - 1)
    
    ' シート名とMarkdownTableでプロンプトを作る
    Dim promptStr As String
    promptStr = "Excelシート「" & ws.Name & "」のセル状態 : """"""" & vbCrLf
    promptStr = promptStr & mdtStr
    promptStr = promptStr & """"""""
    
    Call strToClipboard(promptStr)
End Sub
Function getColName(ByVal colNum As Integer) As String
VBA
Function getColName(ByVal colNum As Integer) As String
    Dim colName As String
    colName = ""
    
    While colNum > 0
        Dim remainder As Integer
        remainder = (colNum - 1) Mod 26
        colName = Chr(65 + remainder) & colName
        colNum = (colNum - 1) \ 26
    Wend
    
    getColName = colName
End Function
Public Sub strToClipboard(ByVal inputStr As String)
VBA
Public Sub strToClipboard(ByVal inputStr As String)
    Dim clipboard As Object
    Set clipboard = CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
    
    With clipboard
        .SetText inputStr       ' 変数のデータをDataObjectに格納する
        .PutInClipboard         ' DataObjectのデータをクリップボードに格納する
        .GetFromClipboard       ' クリップボードからDataObjectにデータを取得する
    End With
End Sub

↑この「strToClipboard」だけ環境により動かないことがあるかもしれません。その場合は「Call strToClipboard(promptStr)」を使用せずに、「Debug.Print promptStr」などで出力してコピーしてもらえれば幸いです。

6.ChatGPTに聞く際のプロンプト例

ChatGPTのモデルはGPT-4を使用しています。名前はダミー情報です。

Excel関数を聞きたいとき

Excel関数を聞きたいときのプロンプト
C列の情報から姓と名を取得したいです。
D10とE10に入力するExcel関数を教えてください。

Excelシート「Sheet1」のセル状態 : """
| ↓行 / 列→ | B | C | D | E |
|---|---|---|---|---|
|9|ID|フルネーム|||
|10|K34a3|下村 愛作|||
|11|K34a4|辻 秋美|||
|12|K34a5|長沢 百世|||
|13|K34a6|藤村 君吉|||
|14|K34a7|沢田 優紀|||
"""

VBAコードを聞きたいとき

VBAコードを聞きたいときのプロンプト
C列の情報から姓と名を取得したいです。
ExcelVBAコードを書いてください。

Excelシート「Sheet1」のセル状態 : """
| ↓行 / 列→ | B | C | D | E |
|---|---|---|---|---|
|9|ID|フルネーム|||
|10|K34a3|下村 愛作|||
|11|K34a4|辻 秋美|||
|12|K34a5|長沢 百世|||
|13|K34a6|藤村 君吉|||
|14|K34a7|沢田 優紀|||
"""

7.おわりに

いずれ日本語版のMicrosoft 365 Copilot(コパイロット)が実装されれば、このコードは不要になるでしょう。それまでの間は非常に便利なVBAマクロだと思うのでぜひお試しください。

Discussion