質問するログイン新規登録

Q&A

解決済

1回答

552閲覧

VBAで複数のデータを好きな位置に配置する方法が分からない

situmonyou

総合スコア1

VBA

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

0グッド

0クリップ

投稿2026/02/10 03:48

0

0

実現したいこと

VBAで複数のテーブル情報を取得してExcelの一枚のシート上に好きな位置に配置したい

発生している問題・分からないこと

イメージ説明
一つ目のデータを貼り付けは出来たと思うが、二つ目以降のデータを配置したいが、一つ目のデータの列数が変動すると思うので、その点をカバーできるように二つ目以降のデータを配置をどのようにすればよいか分からない、また三つ目以降は二つ目のデータの右になど様々な位置に配置できる、次に貼り付ける際には元々入っていたデータを削除してフォーマットは残せるように対応させたい

該当のソースコード

VBA

1Sub MergeExcelFiles() 2 Dim FolderPath As String 'フォルダパス 3 Dim Filename As String 'ファイル名 4 Dim wbSource As Workbook '参照テーブルファイル 5 Dim wsDest As Worksheet '貼り付け先シート 6 Dim LastRow As Long '最終行 7 Dim PasteRow As Long '貼り付け行 8 Dim wsSource As Worksheet '参照テーブル格納データ 9 10 ' まとめ用シートを設定 11 Set wsDest = ThisWorkbook.Sheets("まとめ") 12 wsDest.Cells.Clear ' 古いデータを削除 13 PasteRow = 1 14 15 ' データが入っているフォルダパスを指定(最後に \ を忘れない) 16 FolderPath = "C:\Users\accou\OneDrive\デスクトップ\STAFF_○○\VBA作成テーブル例\" ' ←ここを変更 17 Filename = Dir(FolderPath & "*.xlsx") ' フォルダ内のxlsxを取得 18 19 ' フォルダ内の全ファイルをループ 20 Do While Filename <> "" 21 Set wbSource = Workbooks.Open(FolderPath & Filename) 22 Set wsSource = wbSource.Sheets(1) ' 最初のシートをコピー対象に 23 24 ' コピーする行数を取得(1列目の最終行) 25 LastRow = wsSource.Cells(wsSource.Rows.Count, 1).End(xlUp).Row 26 27 ' ヘッダー行を1回だけコピー 28 ' If PasteRow = 1 Then 29 ' wsSource.Rows(1).Copy wsDest.Rows(PasteRow) 30 ' PasteRow = PasteRow + 1 31 ' End If 32 33 ' データ部分をコピー(2行目以降) 34 If LastRow > 1 Then 35 wsSource.Rows("2:" & LastRow).Copy wsDest.Rows(PasteRow) 36 PasteRow = wsDest.Cells(wsDest.Rows.Count, 1).End(xlUp).Row + 1 37 End If 38 39 wbSource.Close False 40 Filename = Dir ' 次のファイルへ 41 Loop 42 43 MsgBox "データの統合が完了しました!" 44End Sub

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

FileMakerからExcel用に出力し、フォルダ内に格納された複数のファイルのデータをVBAで自動化し配置できることが分かった。また、そのソースコードが分かった。

補足

チャットgptに質問してソースコードを作成しました

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

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

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

sk.exe

2026/02/10 08:15 編集

> VBAで複数のデータを好きな位置に配置する方法 > 複数のテーブル情報を取得してExcelの一枚のシート上に好きな位置に配置 ここでの「好きな位置」というのが、具体的にどのような状況下における、どのような条件に当てはまる「位置」を意味しているのかが不明瞭です。 > フォルダ内に格納された複数のファイル それぞれのブックの 1 番目の(あるいは特定の名前が付けられた)ワークシートから任意のセル範囲/テーブルをコピーし、そのマクロ有効ブックのワークシート[まとめ]上に貼り付けて統合することを主な目的とされていると仮定して、 > 一つ目のデータの列数が変動すると思う コピー元のテーブルの構造(列の数、各列の名前および列位置)は全てのブックにおいて統一されているのか、それともブックによってテーブルの構造が異なる場合があるのか、どちらなのでしょうか。 また、添付された画像が「コピー元のワークシート」と「貼り付け先のワークシート」のどちらを示しているのかが不明です。 したがって、「コピー元のブック/セル範囲と貼り付け先セルを変えながら単純なコピーアンドペーストを繰り返す」だけの処理でよいのか、それとも貼り付けに際して何らかのフロー制御やデータ変換が伴うのかが分かりませんので、現時点では回答のしようがありません。 まずはその辺りの詳しいご説明を追記されることをお奨めします。
meg_

2026/02/11 15:09

「発生している問題・分からないこと」の図を見ると、罫線だけが引かれていて項目名の無い列がいくつもあります。これは「FileMakerからExcel用に出力し、フォルダ内に格納された複数のファイル」がそういう構造になっているということでしょうか?
take88

2026/02/11 17:11 編集

もしかするとですが、FileMakerのリレーションシップグラフのようなものを、Excelシートで再現したいのでしょうか?各ExcelにはFileMakerのテーブルの中身が出力されていて、それを、単一Excelシート上に、自動的に配置させたいのかなと思いました。各テーブルは行数も列数もそれぞれ異なるので、Excelシート上の動的に配置可能な領域を探すロジックが必要になると思いますが、それを質問されてるのかなと。見当違いであればすみません。
situmonyou

2026/02/12 02:22

質問の意図が伝わりづらい提示情報で申し訳ありません。やりたい事としてはUmeeeh様の仰っている「各テーブルは行数も列数もそれぞれ異なるので、Excelシート上の動的に配置可能な領域を探すロジックが必要になると思います」の実装です。End(xlUp)でデータ側は行数の取得が出来ているのですが、配置先の表はバラバラでアルバイトの表にデータを入れたい場合に、データの行数が分からないので配置位置を可変で対応させたいです。 図の項目が無い箇所は抜けていただけです。ファイルの構造ではないです。
sk.exe

2026/02/12 03:58

- あるフォルダに A.xlsx, B.xlsx, C.xlsx というブックが保存されている。 - A.xlsx には、ある日付における各社員の勤怠実績を記録した表(以下「表A」)が 作成されたワークシートがある。 この表のデータ行(列見出し行を除く範囲)の行数は、作成時点における社員人数に応じて その都度変動する。 - B.xlsx には、A.xlsx と同じ日付における各アルバイトの勤怠実績を記録した表 (以下「表B」)が 作成されたワークシートがある。 この表のデータ行の行数は、作成時点におけるアルバイト人数に応じて その都度変動する。 - C.xlsx には、A.xlsx および B.xlsx と同じ日付における売上総額と それに掛かる消費税額を集計した結果を記録した表(以下「表C」)が 作成されたワークシートがある。 この表のデータ行の行数は 1 件のみである。 - あるマクロ有効ブックに[まとめ]というワークシートがある。 このワークシートを貼り付け先として、上記 3 つの表をコピーしようとしている。 - この時、表A, 表B, 表C のそれぞれの表の貼り付け先範囲を、 添付した画像のような位置関係(表A:上、表B:左下、表C:右下)に なるように動的に制御したい。 といったことを目的とされているとして、 1. 表A全体を(データ行の多寡に係わらず)そっくりそのまま [まとめ]の特定のセル範囲(この例では A1 セルを始点とする)に貼り付ける。 2. 上記 1 の貼り付け先範囲より 3 行下のセルを始点として 表B全体をそっくりそのまま貼り付ける。 例えば、表Aの行数(列見出し行とデータ行の総数)が 10 行ならば、 表Bの貼り付け先範囲の始点は A13 セルとなる。 3. 上記 2 の貼り付け先範囲より 3 列右のセルを始点として 表C全体をそっくりそのまま貼り付ける。 例えば、表Aの行数が 10 行、表Bの列数が 5 列ならば、 表Cの貼り付け先範囲の始点は H13 セルとなる。 といったコードを書ければよい、ということでしょうか。
situmonyou

2026/02/12 05:11

sk.exe様の仰る通りの事を目的としています。コードもそのような事が書きたいのですが、表Aや表Bの行数がまとめ表で想定している行数を超えた場合にも対応できる様なコードを書きたいと思っています。その場合に、「表Bの貼り付け先範囲の始点は A13 セルとなる。 」、「表Cの貼り付け先範囲の始点は H13 セルとなる。」と言った始点を変動させる方法が無いかと思案しているのですが、そういった場合は手動でまとめ表の行数を増やしたり、コードを修正したりするしかないのでしょうか?
sk.exe

2026/02/12 05:47 編集

> 次に貼り付ける際には元々入っていたデータを削除してフォーマットは残せるように対応させたい > 表Aや表Bの行数がまとめ表で想定している行数を超えた場合にも対応できる様なコードを書きたい 逆に「想定している行数に満たなかった場合」はどのようになさりたいのでしょうか。 例えば、表Aの貼り付け先として想定されている範囲の行数(の上限?)が 10 行だったとして、 実際の表A全体の行数が 2 行(列見出し行+ 1 件のデータ行)しかなかった場合、 表Bの貼り付け先範囲の始点はワークシート[まとめ]のどのセルになるのでしょうか。 (私が例示した形をそのまま採る場合なら A5 セルということになりますが) いずれにせよ、実際のコピー元範囲が想定された貼り付け先範囲から「溢れた」場合も含めて それらの書式(表示形式や罫線など)を制御したいのであれば、フォーマットを「残す」のではなく 「一から設定し直す」ぐらいでなければ上手くはいかないと思います。
situmonyou

2026/02/12 05:51

sk.exe様回答ありがとうございます。 想定している行数に満たなかった場合についてですが、 sk.exe様の提示条件とした場合 <表Aの貼り付け先として想定されている範囲の行数(の上限?)が 10 行だったとして、 実際の表A全体の行数が 2 件(列見出し行+ 1 件のデータ行)しかなかった場合> その場合には1件のデータが入って残りの9行は空白のまま存在している想定で考えていました。 貼り付け先のシートには項目と集計の為の行を用意しているのでそれを崩さないで張り付ける方法を模索していたのですが、 「それらの書式(表示形式や罫線など)を制御したいのであれば、フォーマットを「残す」のではなく 「一から設定し直す」ぐらいでなければ上手くはいかないと思います。」との助言の通り、フォーマットを残すのは難しい為他の手法を試そうかと思います。皆様ご助言ありがとうございました。
sk.exe

2026/02/12 08:51

> その場合には1件のデータが入って残りの9行は空白のまま存在している想定で考えていました。 恐らく、印刷する上での体裁を整える目的で「空白行にも罫線を引きたい」 といったことなのだろうと思われますが、 > 貼り付け先のシートには項目と集計の為の行を用意しているのでそれを崩さないで張り付ける それは例えば「ある年の 1 月から 12 月までの月ごとの水道料金の内訳」のように、 データ件数が必ず一定の数値内( 1 ~ 12 )に収まることが保証されている場合のみ 有効な手法であると言えます。 今回の例に置き換えるなら「その職場の規模として社員やアルバイトの総数は 最大で何人程度になる可能性があるか」を検討し、その想定し得る人数よりも 更にゆとりを持たせた行数の貼り付け先範囲を設けておく必要があります。 つまり「めったなことでは『溢れ』が生じないようなレイアウト」にしてしまう形です。 それでもデータ件数に上限がない限り「溢れる」可能性をゼロにすることは出来ないわけですが、 そうなった場合は個別に対応する、という運用の仕方もあるでしょう。 いずれにせよ、(具体的にどのような数式が設定されているかにもよりますが) もし実際のデータ行が数式上において参照されている範囲を「溢れた」場合、 それぞれの数式が参照するべき範囲を変更したり、新たな数式セルを追加したり しなければならなくなるはずです。 そういった「ワークシートの修正作業」が発生する可能性をできるだけ排除し、 全てをマクロのみで完結させたいのであれば、Umeeeh さんがおっしゃったように 「動的に配置可能な領域を探す」と共に「数式セルの設定」や「セル書式の設定」 といった処理を一括して実行する形を採られるのが無難でしょう。 (マクロのメンテナンスコストは上がるかも知れませんが)
meg_

2026/02/12 09:16

真にやりたいことって何なのでしょうか?FileMakerをお使いなんですよね?FileMakerで完結できないんでしょうか?
guest

回答1

0

ベストアンサー

とりあえず、コメント欄で確認させていただいた内容を踏まえてサンプルマクロを例示します。

  • 以下に示す 3 つのブックが全て閉じられている( Excel 上で開かれていない)状態で実行するものとする。

  • 変数strSourceFolderにフォルダパスを代入している箇所は適宜書き換えること。

  • 各表の貼り付け先は新規ブック上のワークシートとする(事故防止のため)。

  • このサンプルでは UsedRange プロパティを使用して各表の範囲を参照しているが、あくまでサンプル簡略化のためである。使用に適さない場合もあるので適宜修正すること。

  • セル書式の設定は罫線のみに留める。

  • 数式セルの設定周りに関しては、詳細が不明なのでここでは割愛する。

コピー元ブック

  • A.xlsx

イメージ説明

  • B.xlsx

イメージ説明

  • C.xlsx

イメージ説明

サンプルマクロ

vba

1Sub CopyTables() 2On Error GoTo Err_CopyTables 3 4 '画面の再描画処理を無効化 5 Application.ScreenUpdating = False 6 '数式の再計算方式を「手動」に 7 Application.Calculation = xlCalculationManual 8 9'貼り付け先ワークシートに関する事前処理 10 11 Dim wsDistination As Worksheet 12 Dim rngTarget As Range 13 14 '貼り付け先となるワークシートの参照 15 '(このサンプルでは新規ブックを作成してその 1 番目のワークシートを参照する) 16 Set wsDistination = Workbooks.Add.Worksheets(1) 17 18 '貼り付け先ワークシートの操作 19 With wsDistination 20 'シート名の変更 21 .Name = "まとめ" 22 '最初の貼り付け先始点セルとして A1 セルを参照する 23 Set rngTarget = .Cells(1, 1) 24 End With 25 26 Dim strSourceFolder As String 27 28 'コピー元ブック群が保存されているフォルダの絶対パスを指定 29 strSourceFolder = "C:\FolderName\Source\" 30 31 Dim wbkSource As Workbook 32 Dim wsSource As Worksheet 33 Dim rngSource As Range 34 Dim rngDestination As Range 35 36'表Aのコピー処理 37 38 '表Aのあるブックを読み取り専用で開く 39 Set wbkSource = Workbooks.Open(Filename:=strSourceFolder & "A.xlsx", _ 40 ReadOnly:=True) 41 '1番目のワークシートを参照する 42 Set wsSource = wbkSource.Worksheets(1) 43 'そのワークシートの「使用されている領域」を表Aとして参照する 44 Set rngSource = wsSource.UsedRange 45 46 '表Aをまるごとコピーアンドペースト(値のみコピーではない) 47 rngSource.Copy Destination:=rngTarget 48 49 '貼り付け先となったセル範囲全体を参照 50 Set rngDestination = rngTarget.Resize(RowSize:=rngSource.Rows.Count, _ 51 ColumnSize:=rngSource.Columns.Count) 52 53 Debug.Print "コピー元範囲:" & rngSource.Address(External:=True) 54 Debug.Print "貼り付け先始点セル:" & rngTarget.Address(External:=True) 55 Debug.Print "貼り付け先範囲:" & rngDestination.Address(External:=True) 56 57 '罫線の設定 58 With rngDestination 59 .Borders(xlEdgeTop).LineStyle = xlContinuous 60 .Borders(xlEdgeBottom).LineStyle = xlContinuous 61 .Borders(xlEdgeLeft).LineStyle = xlContinuous 62 .Borders(xlEdgeRight).LineStyle = xlContinuous 63 .Borders(xlInsideHorizontal).LineStyle = xlDot 64 .Borders(xlInsideVertical).LineStyle = xlDot 65 .Rows(1).Borders(xlEdgeBottom).LineStyle = xlDouble 66 .Columns(1).Borders(xlEdgeRight).LineStyle = xlDouble 67 End With 68 69 Set rngDestination = Nothing 70 71 '現在の貼り付け先始点セルから「表Aの行数に 2 を加えた数」だけ下にあるセルを 72 '次の貼り付け先始点セルとして参照。 73 'これにより、表Aと表Bの間に 2 行分の空白行が出来る 74 Set rngTarget = rngTarget.Offset(RowOffset:=rngSource.Rows.Count + 2) 75 76 '開いたブックを閉じる 77 Set wsSource = Nothing 78 wbkSource.Close SaveChanges:=False 79 Set wbkSource = Nothing 80 81'表Bのコピー処理 82 83 '表Bのあるブックを読み取り専用で開く 84 Set wbkSource = Workbooks.Open(Filename:=strSourceFolder & "B.xlsx", _ 85 ReadOnly:=True) 86 '1番目のワークシートを参照する 87 Set wsSource = wbkSource.Worksheets(1) 88 'そのワークシートの「使用されている領域」を表Bとして参照する 89 Set rngSource = wsSource.UsedRange 90 91 '表Bをまるごとコピーアンドペースト(値のみコピーではない) 92 rngSource.Copy Destination:=rngTarget 93 94 '貼り付け先となったセル範囲全体を参照 95 Set rngDestination = rngTarget.Resize(RowSize:=rngSource.Rows.Count, _ 96 ColumnSize:=rngSource.Columns.Count) 97 98 Debug.Print "コピー元範囲:" & rngSource.Address(External:=True) 99 Debug.Print "貼り付け先始点セル:" & rngTarget.Address(External:=True) 100 Debug.Print "貼り付け先範囲:" & rngDestination.Address(External:=True) 101 102 '罫線の設定 103 With rngDestination 104 .Borders(xlEdgeTop).LineStyle = xlContinuous 105 .Borders(xlEdgeBottom).LineStyle = xlContinuous 106 .Borders(xlEdgeLeft).LineStyle = xlContinuous 107 .Borders(xlEdgeRight).LineStyle = xlContinuous 108 .Borders(xlInsideHorizontal).LineStyle = xlDot 109 .Borders(xlInsideVertical).LineStyle = xlDot 110 .Rows(1).Borders(xlEdgeBottom).LineStyle = xlDouble 111 .Columns(1).Borders(xlEdgeRight).LineStyle = xlDouble 112 End With 113 114 Set rngDestination = Nothing 115 116 '現在の貼り付け先始点セルから「表Bの列数に 2 を加えた数」だけ右にあるセルを 117 '次の貼り付け先始点セルとして参照 118 'これにより、表Bと表Cの間に 2 列分の空白列が出来る 119 Set rngTarget = rngTarget.Offset(ColumnOffset:=rngSource.Columns.Count + 2) 120 121 '開いたブックを閉じる 122 Set wsSource = Nothing 123 wbkSource.Close SaveChanges:=False 124 Set wbkSource = Nothing 125 126'表Cのコピー処理 127 128 '表Cのあるブックを読み取り専用で開く 129 Set wbkSource = Workbooks.Open(Filename:=strSourceFolder & "C.xlsx", _ 130 ReadOnly:=True) 131 '1番目のワークシートを参照する 132 Set wsSource = wbkSource.Worksheets(1) 133 'そのワークシートの「使用されている領域」を表Cとして参照する 134 Set rngSource = wsSource.UsedRange 135 136 '表Cをまるごとコピーアンドペースト(値のみコピーではない) 137 rngSource.Copy Destination:=rngTarget 138 139 '貼り付け先となったセル範囲全体を参照 140 Set rngDestination = rngTarget.Resize(RowSize:=rngSource.Rows.Count, _ 141 ColumnSize:=rngSource.Columns.Count) 142 143 Debug.Print "コピー元範囲:" & rngSource.Address(External:=True) 144 Debug.Print "貼り付け先始点セル:" & rngTarget.Address(External:=True) 145 Debug.Print "貼り付け先範囲:" & rngDestination.Address(External:=True) 146 147 '罫線の設定 148 With rngDestination 149 .Borders(xlEdgeTop).LineStyle = xlContinuous 150 .Borders(xlEdgeBottom).LineStyle = xlContinuous 151 .Borders(xlEdgeLeft).LineStyle = xlContinuous 152 .Borders(xlEdgeRight).LineStyle = xlContinuous 153 .Borders(xlInsideHorizontal).LineStyle = xlDot 154 .Columns(1).Borders(xlEdgeRight).LineStyle = xlDouble 155 End With 156 157 Set rngDestination = Nothing 158 159 '開いたブックを閉じる 160 Set wsSource = Nothing 161 wbkSource.Close SaveChanges:=False 162 Set wbkSource = Nothing 163 164'貼り付け先ワークシートの操作 165 166 With wsDistination 167 '列幅の自動調整 168 .UsedRange.EntireColumn.AutoFit 169 'A1 セルを選択 170 .Cells(1, 1).Select 171 'このワークシートのあるブックをアクティブにする 172 .Parent.Activate 173 End With 174 175'終了処理 176Exit_CopyTables: 177On Error Resume Next 178 179 '画面の再描画処理を有効化 180 Application.ScreenUpdating = True 181 '数式の再計算方式を「自動」に 182 Application.Calculation = xlCalculationAutomatic 183 184 Set rngTarget = Nothing 185 Set wsDistination = Nothing 186 187 Exit Sub 188 189'エラー時処理 190Err_CopyTables: 191 192 Dim strErrMsg As String 193 194 strErrMsg = Err.Number & ": " & Err.Description 195 196 Debug.Print strErrMsg 197 198 MsgBox strErrMsg, vbCritical, "実行時エラー (CopyTables)" 199 200 Set wsSource = Nothing 201 If Not wbkSource Is Nothing Then 202 wbkSource.Close SaveChanges:=False 203 Set wbkSource = Nothing 204 End If 205 206 Resume Exit_CopyTables 207End Sub

実行結果

イメージ説明

投稿2026/02/12 09:52

編集2026/02/12 10:15
sk.exe

総合スコア1149

situmonyou

2026/02/13 02:28

回答ありがとうございます。 非常に参考になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.29%

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

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

質問する

関連した質問