🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

2回答

2129閲覧

【VBA】複数ファイル から あるファイル へ転記

peto_123

総合スコア19

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2021/02/14 11:03

前提・実現したいこと

■実現したいこと
転記元ファイルフォルダ内の全ファイルのF4セルから転記先ファイルへ転記したいです。
転記の際、転記先にはファイルごとに行を1行ずつ下に転記させたいです。

■フォルダ構成

│ 転記先.xlsm

└─転記元ファイル
├─A
│ A.xlsx

├─B
│ B.xlsx

└─C
C.xlsx

↑ A,B,Cフォルダは転記元ファイルフォルダ内にあります。A~C.xlsx もそれぞれA~Cフォルダの中にあります。

発生している問題・エラーメッセージ

■問題 - forEachループ処理のインデックスとして用意しているrowIndexがインクリメントされません。 ループ外でrowIndexを1で初期化して、 ループ内でrowIndexをインクリメントしているのですが、 常にrowIndexが1で初期化されています。

該当のソースコード

VBA

1 2' カレントを起点として再帰的にファイル名を取得する 3Sub getFileNameRecursively() 4 Dim path As String 5 path = ThisWorkbook.path & "\転記元ファイル" 6 Call getFilesRecursively(path) 7End Sub 8 9 10' 再帰的にファイル名を取得する 11Sub getFilesRecursively(path As String) 12 Dim fso As FileSystemObject: Set fso = New FileSystemObject 13 Dim objFolder As folder 14 Dim objFile As file 15 16 ' GetFolder(フォルダ名).SubFoldersでフォルダ配下のフォルダ一覧を取得 17 For Each objFolder In fso.GetFolder(path).SubFolders 18 Call getFilesRecursively(objFolder.path) 19 Next 20 21 Dim rowIndex As Integer 22 rowIndex = 1 23 24 For Each objFile In fso.GetFolder(path).Files 25 Call copyString(objFile, rowIndex) 26Debug.Print (rowIndex) 27 rowIndex = rowIndex + 1 28Debug.Print (rowIndex) 29 Next 30 31End Sub 32 33 34Function copyString(objFile As file, rowIndex As Integer) As Integer 35 36 ' 転記元ブックをオブジェクト化する 37 Dim wbOriginal As Workbook 38 Application.Workbooks.Open objFile.path 39 Set wbOriginal = ActiveWorkbook 40 41 ' 転記先ブックをオブジェクト化する 42 Dim wbDestination As Workbook 43 Dim destinationPath As String 44 destinationPath = "C:\Users\ユーザ名\親\子\孫\転記先.xlsm" 45 Application.Workbooks.Open destinationPath 46 Set wbDestination = ActiveWorkbook 47 48 ' 目的の値を取得する 49 Dim target As String 50 target = wbOriginal.Sheets(1).Range("F4") 51 ' 転記元ファイルの(X,1)に入力する 52 wbDestination.Sheets(1).Cells(rowIndex, 1) = target 53 54 copyString = rowIndex 55 56 ' 転記元ファイルを閉じる 57 wbOriginal.Close 58 59End Function

試したこと

実行した結果、転記先にはA1セルに値が転記(上書き)されました。

デバッグでは、
Debug.Print (rowIndex)
と記載し結果をイミディエイトウィンドウで確認したところ値が
1
2
1
2
1
2
と出力されました。

補足情報(FW/ツールのバージョンなど)

Excel2016
Windows10 home

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

いただいたアドバイスをもとに、次のようにrowIndexを外に出したところうまくいきました。

' カレントを起点として再帰的にファイル名を取得する
Sub getFileNameRecursively()
Dim path As String
path = ThisWorkbook.path & "\転記元ファイル"

Dim rowIndex As Integer rowIndex = 1 Call getFilesRecursively(path, rowIndex)

End Sub

' 再帰的にファイル名を取得する
Sub getFilesRecursively(path As String, rowIndex As Integer)
Dim fso As FileSystemObject: Set fso = New FileSystemObject
Dim objFolder As folder
Dim objFile As file

' GetFolder(フォルダ名).SubFoldersでフォルダ配下のフォルダ一覧を取得 For Each objFolder In fso.GetFolder(path).SubFolders Call getFilesRecursively(objFolder.path, rowIndex) Next For Each objFile In fso.GetFolder(path).Files Call copyString(objFile, rowIndex) rowIndex = rowIndex + 1 Next

End Sub

(略)

投稿2021/02/14 15:35

peto_123

総合スコア19

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

再帰の中で初期化されているからでは?

VBA

1 2Sub getFilesRecursively(path As String, rowIndex As Integer) 3 4

とやってrowIndexを持ち回るか、
関数内でなくグローバル変数に持つか、
いっそシートに書き出す時に最終行を求めるようにするか、
といったあたりが解決法だと思います。

投稿2021/02/14 11:21

編集2021/02/14 11:27
jinoji

総合スコア4592

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

peto_123

2021/02/14 15:36

jinojiさま ご回答ありがとうございます。 修正しましたところ、うまくいきました。 大変助かりました。 今後ともよろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問