自作マクロ機能のAIアップグレード:配列の貼り付け
生成系AIの出現により、Excel マクロも随分と作りやすくなった。
そこで今回も、以前作成したものを改めてAIに添削してもらった。
素材となるのはこちら。
infoment.hatenablog.com
この中のうち、配列を指定範Excelでユーザー定義関数を作成。
AIへの指示がこちら。
関数名:PasteArray
引き数 target_range as range 配列を張り付ける開始点
引き数 source_array as variant 張り付けられる配列
引き数 optional transpose_flag as boolean=false 縦横を入れ替えて貼り付け戻り値
0の場合 正常終了
-1の場合 異常終了 ※target_arrayが配列ではない
-2の場合 異常終了 ※配列の次元数が3以上囲に張り付ける機能を作り直してみよう。
出来てきたのがこちら。
Function PasteArray(target_range As Range, source_array As Variant, Optional transpose_flag As Boolean = False) As Integer Dim i As Long, j As Long Dim numRows As Long, numCols As Long On Error GoTo ErrorHandler ' 配列が2次元または1次元であるかどうかを確認 If IsArray(source_array) = False Then PasteArray = -1 Exit Function End If ' 配列の次元数を取得 Select Case True Case IsArray(source_array) If Not (IsArray(source_array) And IsArray(source_array(1))) Then ' 1次元配列の場合 numRows = 1 numCols = UBound(source_array) - LBound(source_array) + 1 Else ' 2次元配列の場合 numRows = UBound(source_array, 1) - LBound(source_array, 1) + 1 numCols = UBound(source_array, 2) - LBound(source_array, 2) + 1 End If Case Else PasteArray = -2 Exit Function End Select ' 縦横を入れ替える場合 If transpose_flag Then For i = 1 To numCols For j = 1 To numRows target_range.Cells(i, j).Value = source_array(j, i) Next j Next i Else For i = 1 To numRows For j = 1 To numCols target_range.Cells(i, j).Value = source_array(i, j) Next j Next i End If PasteArray = 0 Exit Function ErrorHandler: PasteArray = -1 End Function
なるほど、一次元も二次元も、ともに二次元配列にしたうえで張り付けるのか。
ちなみに、以前作成した際に不便だった点は、文字列が配列に格納されると同時に数値に変換されてしまうことだった。追加で指示してみよう。
Function PasteArray(target_range As Range, source_array As Variant, Optional transpose_flag As Boolean = False) As Integer Dim i As Long, j As Long Dim numRows As Long, numCols As Long On Error GoTo ErrorHandler ' 配列が2次元または1次元であるかどうかを確認 If IsArray(source_array) = False Then PasteArray = -1 Exit Function End If ' 配列の次元数を取得 Select Case True Case IsArray(source_array) If Not (IsArray(source_array) And IsArray(source_array(1))) Then ' 1次元配列の場合 numRows = 1 numCols = UBound(source_array) - LBound(source_array) + 1 Else ' 2次元配列の場合 numRows = UBound(source_array, 1) - LBound(source_array, 1) + 1 numCols = UBound(source_array, 2) - LBound(source_array, 2) + 1 End If Case Else PasteArray = -2 Exit Function End Select ' 縦横を入れ替える場合 If transpose_flag Then For i = 1 To numCols For j = 1 To numRows target_range.Cells(i, j).Value = CStr(source_array(j, i)) Next j Next i Else For i = 1 To numRows For j = 1 To numCols target_range.Cells(i, j).Value = CStr(source_array(i, j)) Next j Next i End If PasteArray = 0 Exit Function ErrorHandler: PasteArray = -1 End Function
さらに、列の次元数を取得したうえで、縦横を入れ替えた配列を取得する部分を切り出して別の関数で作成してみよう。
'[用 途] ' 指定セルに配列を貼り付ける。 '[引 数] ' target_range As Range 配列を貼り付けるセル ' source_array As Variant 貼り付けられる配列 '[戻り値] ' 0の場合 正常終了 ' -1の場合 異常終了 ※target_arrayは配列ではない。 ' -2の場合 異常終了 ※配列の次元数が3以上。
' 配列の次元数を取得する関数 Function GetArrayDimensions(arr As Variant) As Integer Dim dimCount As Integer dimCount = 0 On Error Resume Next Do dimCount = dimCount + 1 Loop Until IsEmpty(LBound(arr, dimCount)) On Error GoTo 0 GetArrayDimensions = dimCount - 1 End Function
' 配列の縦横を入れ替える関数 Function TransposeArray(arr As Variant) As Variant Dim numRows As Long numRows = UBound(arr, 1) Dim numCols As Long numCols = UBound(arr, 2) Dim result() As Variant ReDim result(1 To numCols, 1 To numRows) Dim i As Long Dim j As Long For i = 1 To numRows For j = 1 To numCols result(j, i) = arr(i, j) Next Next TransposeArray = result End Function
' 配列を指定したセル範囲に貼り付ける関数 Function PasteArray(target_range As Range, source_array As Variant, Optional transpose_flag As Boolean = False) As Integer On Error GoTo ErrorHandler ' 配列が有効であるかどうかを確認 If Not IsArray(source_array) Then PasteArray = -1 Exit Function End If ' 配列の次元数を取得 Dim arrayDimensions As Integer arrayDimensions = GetArrayDimensions(source_array) If arrayDimensions > 2 Then PasteArray = -2 Exit Function End If ' 配列の縦横を入れ替えるかどうかをチェック Dim transposedArray As Variant If transpose_flag Then If arrayDimensions = 1 Then ' 1次元配列の場合、単純に縦横を入れ替える Dim numRows As Long numRows = UBound(source_array) - LBound(source_array) + 1 Dim numCols As Long numCols = 1 ReDim transposedArray(1 To numRows, 1 To numCols) Dim i As Long For i = 1 To numRows transposedArray(i, 1) = source_array(i) Next i Else ' 2次元配列の場合、TransposeArray関数を使用 transposedArray = TransposeArray(source_array) numRows = UBound(transposedArray, 1) numCols = UBound(transposedArray, 2) End If Else transposedArray = source_array If arrayDimensions = 1 Then numRows = 1 numCols = UBound(source_array) - LBound(source_array) + 1 Else numRows = UBound(source_array, 1) numCols = UBound(source_array, 2) End If End If ' 値をセルに貼り付ける Dim j As Long For i = 1 To numRows For j = 1 To numCols target_range.Cells(i, j).Value = CStr(transposedArray(i, j)) Next Next PasteArray = 0 Exit Function ErrorHandler: PasteArray = -1 End Function
結果として、元々作成したものに似た形になってしまった。文字列として値を貼り付ける点が改善されたため、これも一つの進化系といえるかな。AIさん、さすがです。
参考まで。