[VBA] 配列の要素を一括で検証する方法

このQ&Aのポイント
  • VBAを使用してデータの処理をする際に、csvファイルのタイトル行の検査方法について質問です。
  • 現在の方法では、配列内の要素を一つずつ検証する必要がありますが、一気に検証する方法はないのでしょうか?
  • また、配列に取り込む際にブックをアクティブにしないとエラーが発生する理由についても教えてください。
回答を見る
  • ベストアンサー

[VBA] 配列の要素を一括で検証する方法

こちらの識者の方々にはいつもお世話になっています。 VBAの質問です。 環境は下記になります。 OS=windowsXP SP3 Office=Excel2003(11.8347.8403) SP3 会社などで一般的にVBAを使用してデータの処理をする場合、自動で吐き出されるcsvファイルを読み込んで、そのデータを加工し、使いたいデータに成型する。というケースが往々にしてあると思うのですが、吐き出されるcsvファイルのタイトル行が今までのものと同一でない(フィールドが知らないうちに増えたり減ったりしている)場合を想定し、csvファイルを取り込んだ時点でタイトル行の検査をしたいのですが、csvファイルのタイトル行を一旦配列に格納し、あらかじめ用意しておいたタイトル行のデータと比較する場合、配列内の一要素ずつ検査するしかないのでしょうか? 例としてはタイトル行が "品名", "4月", "5月", "6月", "7月", "8月", "9月" と仮定し、 Sub test()  Dim EndClm As Long  Dim TitleA As Variant  Dim TitleB As Variant  Dim i As Long  EndClm = Sheets(1).Cells(1, Columns.Count).End(xlToLeft).Column  TitleA = Workbooks("aa.csv").Sheets(1).Range(Sheets(1).Cells(1, 1),Sheets(1).Cells(1, EndClm)) 'csvファイルのタイトル行  TitleB = ThisWorkbook.Sheets(1).Range(Sheets(1).Cells(1, 1), Sheets(1).Cells(1, EndClm)) '検証用 "品名", "4月", "5月", "6月", "7月", "8月", "9月"  For i = 1 To UBound(TitleA, 2)   If TitleA(1, i) <> TitleB(1, i) Then MsgBox "項目が変更されています"  Next i End Sub のようなコードで1つずつ検証できますが、配列内の要素を一気に検証する方法はありますか? 当然通りませんが If TitleA <> TitleB Then MsgBox "項目が変更されています" のような感じです。 短いコードで確実にタイトル行の検査が行われれば、上記の配列に取り込んで要素を検証することに特に頓着はしていません。 今このテストコードを自宅のWindows7,Excel2010で書いていて思ったのですが、TitleA、TitleB共に配列に取り込む際、ブックをアクティブにしないとエラーが起きてしまいます。 もしよろしければこの原因も併せて教えていただいてもよろしいでしょうか。 質問に不備不足等ございましたらご指摘ください。 ご面倒お掛けしますがよろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.2

こんにちは。 まず、修正を加えるなら、こんな感じ。 ' ' /// Sub testA()   Dim EndClm As Long   Dim TitleA As Variant   Dim TitleB As Variant   Dim i As Long   With ThisWorkbook.Sheets(1)     EndClm = .Cells(1, Columns.Count).End(xlToLeft).Column     TitleB = .Cells(1).Resize(, EndClm) '検証用 "品名", "4月", "5月", "6月", "7月", "8月", "9月"   End With   TitleA = Workbooks("aa.csv").Sheets(1).Cells(1).Resize(, EndClm) 'csvファイルのタイトル行, "7月", "8月", "9月"   For i = 1 To EndClm     If TitleA(1, i) <> TitleB(1, i) Then       MsgBox "項目が変更されています"       Exit For     End If   Next i End Sub ' ' /// "短いコード"とは言い難いですが、ループしない方法もある、ということで以下。 ' ' /// Sub testJ()   Dim EndClm As Long   Dim TitleA As Variant   Dim TitleB As Variant   With ThisWorkbook.Sheets(1)     EndClm = .Cells(1, Columns.Count).End(xlToLeft).Column     TitleB = .Cells(1).Resize(, EndClm) '検証用 "品名", "4月", "5月", "6月", "7月", "8月", "9月"   End With   TitleA = Workbooks("aa.csv").Sheets(1).Cells(1).Resize(, EndClm) 'csvファイルのタイトル行, "7月", "8月", "9月"   If Join(Application.Transpose(Application.Transpose(TitleA)), vbCr) _     <> Join(Application.Transpose(Application.Transpose(TitleB)), vbCr) _   Then MsgBox "項目が変更されています" End Sub ' ' /// 要するにタイトルすべてを連結した文字列を比較する、という方法です。 単行複列の二次元配列を、ワークシート関数のTRANSPOSEに2回掛けると一次元配列が返ります。 一次元配列をJoin関数で連結した文字列を比較します。 (vbCrを区切り文字に指定するのは、セル内で使わることがない文字だからです。) 実践的には普通にループする方法の方が却って無駄が無いように思いますが、 ループしないことを好む向きもありましょうから、紹介まで。 csvファイルについては、単にテキストファイルとしての扱いが可能ですから、   Open "aa.csv" For Input As #1     Line Input #1, TitleA   Close #1 とかで、そのままタイトル行だけcsvテキストを取得しちゃう方が 部分的には簡単で処理も速く、正攻法な気がします。 (タイトル行に引用符を使うようなcsvだとシートとの比較が難しいですけれど) 比較するのが、どちらもcsvという場合なら、かなりの説得力を持って奨められるところですが、 片方がExcelブックだとちょっとアンバランスな漢字がするかも、です。 ' ' /// Sub testC() '   Dim EndClm As Long   Dim TitleA As Variant   Dim TitleB As Variant   Dim nFree As Integer   With ThisWorkbook.Sheets(1)     EndClm = .Cells(1, Columns.Count).End(xlToLeft).Column     TitleB = .Cells(1).Resize(, EndClm) '検証用 "品名", "4月", "5月", "6月", "7月", "8月", "9月"   End With   nFree = FreeFile   Open "aa.csv" For Input As #nFree     Line Input #nFree, TitleA   Close #nFree   If TitleA <> Join(Application.Transpose(Application.Transpose(TitleB)), ",") _   Then MsgBox "項目が変更されています" End Sub ' ' /// さて、本題の「列内の要素を一気に検証する方法はありますか?」 というご質問について。 単行または単列の二次元配列または一次元配列を 丸ごと比較する機能、についてですが、 (#最近思いだしたのですが)ユーザー設定のリストを使う方法が簡単といえば簡単です。 但し、Excel2007以降の場合は、Excel97-2003互換ブックからの実行に限定されます。 これは裏技ですから、堂々と人に奨めるようなものではないです。 ' ' /// Sub testAJ()   Dim EndClm As Long   Dim TitleA As Variant   Dim TitleB As Variant   Dim i As Long   With ThisWorkbook.Sheets(1)     EndClm = .Cells(1, .Columns.Count).End(xlToLeft).Column     TitleB = .Cells(1).Resize(, EndClm) '検証用 "品名", "4月", "5月", "6月", "7月", "8月", "9月"   End With   TitleA = Workbooks("aa.csv").Sheets(1).Cells(1).Resize(, EndClm) 'csvファイルのタイトル行, "7月", "8月", "9月"   With Application     .AddCustomList TitleB  ' 配列を引数にユーザー設定のリストを追加 ' ' 引数にした配列がユーザー設定のリストの何番目にあるかを取得。無ければ、0。     If .GetCustomListNum(TitleA) = 0 Then MsgBox "項目が変更されています"     .DeleteCustomList .CustomListCount  ' 追加したユーザー設定のリストを削除して元に戻す。   End With End Sub ' ' /// 結論っぽいことを書くなら、お奨めするなら最初に挙げたtestAです。 個人的には、どれでも許せる記述ですけれど、人によって意見は分かれそうです。 そういう意味では、testAのように万人が理解できるものが一番安心して使える、と思います。

rihitomo
質問者

お礼

:testA 修正ありがとうございます。 たしかにRangeとCellsを組み合わせるよりかはResizeプロパティで書いたほうがすっきりしますね。 :testJ transpose関数自体を知りませんでした。 Redimでは配列の次元数自体を変更できないようなのであきらめていたんですが、こういう技もあるんですね。 :testC ブックを開かずデータを読み込む方法があるんですね。 たしかにこれだと、開く前に検査だけできるので使いやすいです。 :testAJ 配列の要素を一気に検証する方法も教えていただきありがとうございます。 やはり一般的ではないんですね。 おすすめ通りtestAか、両方csvの場合はtestCでやりたいと思います。 transpose関数を使った配列の次元数変更はとても参考になりました。 ありがとうございました。

その他の回答 (1)

回答No.1

後半のエラーは、range(cells, cells)の形で複数のブックを扱う場合、cellsがどのブックか指定する必要があります。つまり Workbooks.sheets.range(Workbooks,sheets,cells, Workbooks.sheets,cells) もちろん冗長になるのでwithを使うとスッキリします。

rihitomo
質問者

お礼

ご回答ありがとうございます。 仰る通りでした。 bookを指定するのを忘れていました。

関連するQ&A

  • VBAの動的配列について

    いつもお世話になっております。 エクセルVBAを学習中の者です。 動的配列についてお伺いします。 添付資料を見て頂きたいのですが、 シート名1~4に同一レイアウトの表があります。 これらの表をを2次元配列に格納し、その後、同一レイアウトのシートに一括転記したいと考えています。 転記の事を考えて、条件としては、 シート1から2行目以降のデータを配列『data』に格納、変数『dataCnt』が転記先の行番号と同じになるように考えています。 当初は、配列の定義を『Dim data(100,3) As Variant』と、多めに要素数を定義して、コードを記述していました。 正直、凄く気持ちが悪い感じでした・・・ 最近、動的配列を学習しまして、 シートごとにデータの行数を変数『lastRow』に格納して、配列を再定義して【データ数=要素数】とならないか? と思い、下記のようなコードを書いてみました。 が、『ReDim Preserve~』で実行エラーが発生してしまいます。 原因がなぜかわかりません! そもそも、動的配列はこのような使い方は出来ないのでしょうか? Sub テスト() Dim data() As Variant Dim x As Long Dim i As Long Dim ii As Long Dim lastRow As Long Dim dataCnt As Long dataCnt = 2 For x = 2 To 5 Worksheets(x).Activate lastRow = Cells(Rows.Count, 1).End(xlUp).Row If x = 2 Then ReDim data(2 To lastRow, 3) Else ReDim Preserve data(2 To dataCnt + lastRow - 1, 3) End If For i = 2 To lastRow For ii = 1 To 3 data(dataCnt, ii) = Cells(i, ii) Next ii dataCnt = dataCnt + 1 Next i Next x End Sub どなたかご指導をよろしくお願いいたします。

  • EXCEL VBAの配列でわかりません。

    こんなコードがあるのですが、最後の他のシート(作業中シート)に書き込もうとするとエラーになってしまいます。”Sheets("作業中").”を抜くと同じシートに結果は返ってくるのですが…。コードの内容は、ある範囲のある列から空白ではないセルを探し出してその行のデータを配列で汲み取り、他のシートに一括で洗い出すというものです。 Sub 作業中() Dim myRow As Long Dim Data As Variant Dim WC() As Variant Dim WCE() As Variant myRow = Range("H1").CurrentRegion.Rows.Count Data = Range("H1:M" & myRow).Value For i = 1 To myRow If Data(i, 5) <> "" Then a = a + 1 Else b = b + 1 End If Next ReDim WC(a) ReDim WCE(b) c = 0 d = 0 For i = 1 To myRow If Data(i, 5) <> "" Then WC(c) = Range("H" & i & ":K" & i).Value c = c + 1 Else WCE(d) = Range(Cells(i, 8), Cells(i, 11)).Value d = d + 1 End If Next For i = 0 To a Range(Cells(i + 1, 15), Cells(i + 1, 18)).Value = WC(i) Next For i = 0 To b Range(Cells(i + 1, 19), Cells(i + 1, 22)).Value = WCE(i) Next e = Range(Cells(1, 15), Cells(a, 18)).Value Sheets("作業中").Range(Cells(1, 1), Cells(a, 4)).Value = e End Sub ちなみに同じシートから↓のコードを実行するとうまくいきます。 なぜ~??わからな~い??おしえてくださーい!! Sub test() Dim a As Variant a = Range("H1:K4") Sheets("作業中").Range("N1:Q4") = a End Sub

  • Excel(VBA)で配列の要素数を調べるには?

    お世話になります。 ExcelのVBAで、split関数を使って配列に格納したデータの要素数を調べる方法がわかりません。 下記のようなコードで、読み込んだデータを配列(Arraydata)に格納することは出来たのですが、test.csvの要素数が処理の度に変わるため、要素数に応じて後続の処理を行ないたいと考えています。 Open test.csv For Input As #1 ' test.csvファイルを開く Line Input #1, test.csv ' データ行を読み込む Arraydata = Array(Split(test.csv, ",")) ' 配列に格納 よろしくお願いします。

  • VBAで配列のある部分だけをを配列に入れたい

    VBAを勉強をしております。 例えばA1からG20までをある配列に入れているとします。 その配列のある部分(例えばB1からC20)を、別の配列にいれるにはどうすれば良いのでしょうか。 以下の方法で試してみましたが、上手くいきません。 Dim A() As Variant Dim B() As Variant A = Range("A1:G20") B = Range(Cells(A(1,2),Cells(A(20,3)))

  • エクセルVBAの配列について

    エクセルVBAの配列について VBAをはじめたばかりの初心者です。 現在、下記のようにデータを配列の中に入れ、 別シートに書き出そうとしております。 (配列へ読み込むところのみ) Dim 配列(1 To 件数, 1 To 9) As Variant For j =1 To 件数 For i = 2 To L If Cells(i, 2).Value = Tx_month Then For k = 3 To 11 配列(j, k - 2) = Cells(i, k).Value Next k End If Next j,i 現状では、データの最終行のみを「件数」分書き出してしまいます。 jとiのForが重なっているからだと思うのですが、どう書き直したら良いか分かりません。 質問をさせていただくのも初めてなので、分かりづらく恐縮ですが お力添え頂けますと幸いです。 どうぞ宜しくお願い致します。

  • ExcelのVBAの配列に関する質問です。

    ExcelのVBAの配列に関する質問です。 sheet1のデータをsheet2に表示するVBAを作成しています。。 sheet1のデータは7行目からスタートし、sheet2のデータは26行目からスタートしています。。 sheet1とsheet2の列は同じ並びではないため、それぞれのシートの列番号をCellsを用いて指定しています。 Sub test1() Dim endrow As Long endrow = Worksheets("sheet1").Range("A65536").End(xlUp).Row Dim i As Long Dim j As Long For i = 7 To endrow j = i + 19 Worksheets("sheet2").Cells(j, 1) = Worksheets("sheet1").Cells(i, 2) Worksheets("sheet2").Cells(j, 8) = Worksheets("sheet1").Cells(i, 28) Worksheets("sheet2").Cells(j, 9) = Worksheets("sheet1").Cells(i, 31) Worksheets("sheet2").Cells(j, 10) = Worksheets("sheet1").Cells(i, 32) ・ ・ ・ ※長いので省略 Next i End Sub 上記のtest1は正常に動くのですが、データ量が多いため、処理に時間がかかってしまいます。 高速化できないかと、以下のように変更しました。 Sub test2() Dim dataRange1 As Variant Dim dataRange2 As Variant dataRange1 = Worksheets("sheet1").Range("A1:GI10006") dataRange2 = Worksheets("sheet2").Range("A1:DZ10018") Dim endrow As Long endrow = Worksheets("sheet1").Range("A65536").End(xlUp).Row Dim i As Long Dim j As Long For i = 7 To endrow j = i + 19 dataRange2(j, 1) = dataRange1(i, 2) dataRange2(j, 8) = dataRange1(i, 28) dataRange2(j, 9) = dataRange1(i, 31) dataRange2(j, 10) = dataRange1(i, 32) ・ ・ ・ ※長いので省略 Next i End Sub test2は、エラーメッセージ等は表示されませんが、sheet2にデータが表示されません。 ちなみに、以下のようにsheet1のみ配列化した場合は、正常に表示されました。 Worksheets("sheet2").Cells(j, 1) = dataRange1(i, 2) Worksheets("sheet2").Cells(j, 8) = dataRange1(i, 28) Worksheets("sheet2").Cells(j, 9) = dataRange1(i, 31) Worksheets("sheet2").Cells(j, 10) = dataRange1(i, 32) test2は、どこが間違っているのでしょうか? ご教示ください。 よろしくお願いいたします。

  • [VBA]二次元配列を使ったsumif

    こちらの識者の方々にはいつもお世話になっています。 VBAの質問です。 環境は下記になります。 OS=windowsXP SP3 Office=Excel2003(11.8347.8403) SP3 vbaでワークシート関数でいうsumifにあたる計算をしたいのですが、自分なりに二次元配列でコードを書いたものの、それでも時間がかかりすぎるため質問させていただきます。 :Sheet1      4月   5月   6月   7月 りんご  20    10   31 みかん  50        40    20 バナナ  35    15   20 りんご       52   50    65 ぶどう           32    63 みかん  21        23    50 のようなデータが約40,000行存在します。 これをSheet2に      4月   5月   6月   7月 りんご  20    62   81   65 みかん  71    0    63   70 バナナ  35    15   20    0 ぶどう  0     0   32    63 のような形で集計したいのです。 自分で書いたコードは下記です。 Option Explicit Option Base 1 Sub test()  Dim SourAry As Variant  Dim DestAry As Variant  Dim SourEndRow As Long  Dim DestEndRow As Long  Dim i As Long  Dim j As Long  Dim k As Long  Dim TTL As Long  Application.ScreenUpdating = False  SourEndRow = Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row  DestEndRow = Sheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Row  SourAry = Sheets("Sheet1").Range("A2:E" & SourEndRow).Value  DestAry = Sheets("Sheet2").Range("A2:E" & DestEndRow).Value  For i = 2 To 5   For j = 1 To UBound(DestAry)    For k = 1 To UBound(SourAry)     If SourAry(k, 1) = DestAry(j, 1) Then TTL = TTL + SourAry(k, i)     DestAry(j, i) = TTL    Next k    TTL = 0   Next j  Next i  Sheets("Sheet2").Range("A2:E" & DestEndRow).Value = DestAry  Application.ScreenUpdating = True End Sub これでも一応希望通りの結果は得られるのですが、40,000行ともなると配列で処理したとしてもとても時間がかかってしまいます。 ご教示いただきたいことは、もっと効率のいいコードなのですが、実は実際のデータはSheet1とSheet2のA列のデータは昇順で並んでおります。 後学のためにもしよろしければ下記2パターンを教えて戴けませんでしょうか。 1.キーとなるフィールドが昇順で並んでいる場合 2.キーとなるフィールドの順番がばらばらで、かつ並び替えることができない場合(A列総当たり) 2.のパターンの場合、コードによると思いますが、総当たりよりかはやはり並び替えた方が効率はいいものなのでしょうか? 質問に不備不足等ございましたらご指摘ください。 ご面倒お掛けしますがよろしくお願いします。

  • VBAの配列について

    初めまして、VBAの配列の入力方法について質問させてください。 大量のデータの処理を高速化するため、配列を使用して以下のVBAを入力しました。 インターネットで調べ、見よう見まねで入力してみたものです…(T_T) 内容は、シート「資料」のC列とシート「Sheet1」のG列の文字列が同じ かつ、シート「資料」のL列から最終列(そのときによって変化します) とシート「Sheet1」のE列の文字列が同じ場合、 シート「資料」のA列~D列及びL列から最終列で文字列の一致したセルを 着色するというものです。 変数「アイス」と「チョコ」にそれぞれシート「資料」のデータと シート「Sheet1」のデータを格納したつもりなのですが、 実行したところ「配列がありません。」というエラーメッセージが 表示されました。 どうやらデータを配列として格納できていないときに表示される エラーメッセージのようなのですが、変数の型を変更してみたり、 配列をアイス(2)にしてみたりと、色々方法を変えて試してみたものの、 処理は成功しませんでした(T_T) 一体何が原因で処理が成功しないのか、どなたかご教授いただけると とても嬉しいです…!よろしくお願いいたします。 ちなみに、配列を使用しない場合の処理は、時間が15分ほどと かなりかかりますが、成功しています。 Application.ScreenUpdating = True Dim アイス, チョコ As Long Dim i As Integer, j As Integer, k As Integer アイス = Sheets("資料").Cells(Rows.Count, 1).End(xlUp).Row チョコ = Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row For i = 3 To Sheets("資料").Cells(Rows.Count, 1).End(xlUp).Row For j = 12 To Sheets("資料").Cells(i, 12).End(xlToRight).Column For k = 2 To Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row If アイス(i, 3).Value = チョコ(k, 7).Value And アイス(i, j).Value = チョコ(k, 5).Value Then Sheets("資料").Range("A" & i & ":D" & i).Interior.ColorIndex = 22 アイス(i, j).Interior.ColorIndex = 22 End If Next k Next j Next i

  • Excelのセルから配列変数への一括読込み

    VB(というかプログラミング)の超初心者です。 Excelシートの任意の領域にある数値を、配列変数に一括して 入力したいと思っています。 これまで、 Dim XXX(10) As Variant For I = 1 To 10 XXX(I - 1) = Cells(1, I).Value Next I Range(Cells(10, 1), Cells(10, 10)).Value = XXX の様な感じで処理していましたが(最近まで、セルへの書込みも For-Nextで処理していました)、データ数が多くなると処理に 時間がかかってしまいます。 配列YYYへの読込みもセルへの書込みの様に一括して行うには どうすれば良いでしょうか? よろしくお願いします。

  • EXCEL、VBAについて

    ' GLOBAL変数の定義 Dim CurrentDir As String '現在のディレクトリ Dim ThisBook As String '現在のブック名 Dim WorkSheetName1 As String Dim WorkSheetName2 As String Dim ConfigSheetName As String Dim ListSheetName1 As String Dim ListSheetName2 As String Dim ListSheetName3 As String Dim ListSheetName4 As String Dim ListSheetName5 As String Dim ListSheetName6 As String Dim ListSheetName7 As String Dim ErrorFlag As Integer 'エラーフラグ 0:正常 1:エラー Sub 初期設定() CurrentDir = ActiveWorkbook.Path '現在のディレクトリ ThisBook = ActiveWorkbook.Name '現在のブック名 WorkSheetName1 = "work1" WorkSheetName2 = "work2" ConfigSheetName = "設定" ListSheetName1 = "****" ListSheetName2 = "****" ListSheetName3 = "****" ListSheetName4 = "****" ListSheetName5 = "****" ListSheetName6 = "****" ListSheetName7 = "****" Application.DisplayAlerts = False 'EXCELの警告を無視する End Sub Sub CSV取り込み() Dim LoadBook As String '読み込みブック名 Dim DataMaxCol As Integer '読み込みデータ有効最大カラム数 Dim WorkStartRow As Integer 'workシート開始行 Dim WorkEndRow As Integer 'workシート終了行 Dim ListMaxCol As Integer '一覧シート有効最大カラム数 Dim ListStartRow As Integer '一覧シート開始行 '初期設定コール Call 初期設定 'workシートをクリア DataMaxCol = Sheets(ConfigSheetName).Range("F2").Value WorkStartRow = Sheets(ConfigSheetName).Range("F3").Value WorkEndRow = Sheets(ConfigSheetName).Range("F4").Value Sheets(WorkSheetName1).Select Range(Cells(WorkStartRow, 1), Cells(WorkEndRow, DataMaxCol)).ClearContents '受注データファイルを選択しオープン SelectedPath = Application.GetOpenFilename("CSVファイル (*.csv), *.csv") If SelectedPath <> "False" Then Workbooks.Open Filename:=(SelectedPath) Else 'キャンセル時は終了 Exit Sub End If LoadBook = ActiveWorkbook.Name '現在のブック名 '受注データの開始行をチェック I = WorkStartRow '受注データの最終行をチェック Do Until ActiveCell.Value = "" I = I + 1 Cells(I, 1).Select Loop WorkEndRow = I - 1 '受注データをコピー Range(Cells(WorkStartRow, 1), Cells(WorkEndRow, DataMaxCol)).Select Selection.Copy 'workシートへペースト Windows(ThisBook).Activate Sheets(WorkSheetName1).Select Range("A1").PasteSpecial Paste:=xlPasteValues Application.CutCopyMode = False '受注データファイルをクローズ Windows(LoadBook).Close End Sub このマクロを実行するとインデックスが有効範囲にありませんとなりエラーとなってしまいます。 あと最後のデータファイルをクローズできればOKなのですが・・。 どこがいけないんでしょうか?

専門家に質問してみよう