生成AIを使いVBAのフォームを生成してもらう方法

最近Claude3.5でプログラムを作ることが多くなっていますが、Excelのブックからシート一覧からシートを選ぶよう指示すると、シート名を直接入力するようなコードを生成してしまいがちです。

そうでなければ手作業でフォームを作れとか言ってきたりして、それでも手間は減りますが、どうせなら生成してほしいところです。

Visual Basic For Applications Extensibilityを使うことを指示する

フォームのインポートファイルを生成してもらいましたが、このファイルはどうやらバイナリーのようで、今のところ生成AIではバイナリーコードまでは学習して生成はしてくれないようです。

色々調べてみると、どうやらコードでフォームを生成してくれる拡張機能(参照設定:Microsoft Visual Basic for Application Extensibility)があるようです。それを使うよう指示してみました。

Option Explicit

Sub CreateSheetSelectorForm()
Dim vbProj As VBIDE.VBProject
Dim vbComp As VBIDE.VBComponent
Dim codeModule As VBIDE.CodeModule
Dim formName As String' プロジェクト参照を設定
Set vbProj = ThisWorkbook.VBProject

' フォーム名を設定
formName = "SheetSelectorForm"

' 既存のフォームがあれば削除
On Error Resume Next
vbProj.VBComponents.Remove vbProj.VBComponents(formName)
On Error GoTo 0

' 新しいフォームを追加
Set vbComp = vbProj.VBComponents.Add(vbext_ct_MSForm)
vbComp.Name = formName

' フォームのプロパティを設定
With vbComp.Designer
    .Caption = "シート選択"
    .Width = 300
    .Height = 200
End With

' コントロールを追加
AddListBox vbComp, "lstSheets", 10, 10, 280, 140
AddCommandButton vbComp, "cmdOK", "OK", 120, 160, 80, 25

' コードを追加
Set codeModule = vbComp.CodeModule
With codeModule
    .InsertLines .CountOfLines + 1, "Private Sub UserForm_Initialize()"
    .InsertLines .CountOfLines + 1, "    Dim ws As Worksheet"
    .InsertLines .CountOfLines + 1, "    For Each ws In ThisWorkbook.Worksheets"
    .InsertLines .CountOfLines + 1, "        lstSheets.AddItem ws.Name"
    .InsertLines .CountOfLines + 1, "    Next ws"
    .InsertLines .CountOfLines + 1, "End Sub"
    .InsertLines .CountOfLines + 1, ""
    .InsertLines .CountOfLines + 1, "Private Sub cmdOK_Click()"
    .InsertLines .CountOfLines + 1, "    If lstSheets.ListIndex <> -1 Then"
    .InsertLines .CountOfLines + 1, "        MsgBox ""選択されたシート: "" & lstSheets.Value"
    .InsertLines .CountOfLines + 1, "    Else"
    .InsertLines .CountOfLines + 1, "        MsgBox ""シートを選択してください"""
    .InsertLines .CountOfLines + 1, "    End If"
    .InsertLines .CountOfLines + 1, "End Sub"
End With

' フォームを表示
Application.Run formName & ".Show"

End Sub
Sub AddListBox(frm As VBComponent, name As String, left As Integer, top As Integer, width As Integer, height As Integer)
Dim ctl As Object
Set ctl = frm.Designer.Controls.Add("Forms.ListBox.1")
With ctl
.Name = name
.left = left
.top = top
.width = width
.height = height
End With
End SubSub AddCommandButton(frm As VBComponent, name As String, caption As String, left As Integer, top As Integer, width As Integer, height As Integer)
Dim ctl As Object
Set ctl = frm.Designer.Controls.Add("Forms.CommandButton.1")
With ctl
.Name = name
.Caption = caption
.left = left
.top = top
.width = width
.height = height
End With
End Sub

ということでこんなコードを吐いてくれました。はたして動くかどうか。明日ためしてみよう。

試した結果

上記のコードでは動かなかったですね。まず、セキュリティ設定が必要で、ファイル/オプションのトラストセンター/マクロの設定で、「VBAプロジェクトのオブジェクトモデルへのアクセスを信頼」をチェックする必要があるようです。

また、内部のListBoxとかはコードで生成することはできますが、フォーム(枠)自身は手作業で追加する必要があり、フォームのオブジェクト名は指定してあげる必要があるようです。

あとは大きさが合わない場合もあるので、大きさも指定が必要なのと、コードは標準モジュールとフォームとで分けて生成してもらう必要があります。

フォーム作成の作業は手作業で残りますがあとはなんとか自動成績することができそうです。



この記事が気に入ったらサポートをしてみませんか?