質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

VBA

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

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

Q&A

1回答

4207閲覧

Excelファイル間のデータ転記(転記元ファイルの表の行数がファイルによって異なる)

2134

総合スコア3

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

VBA

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

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

0グッド

0クリップ

投稿2020/05/15 06:21

前提・実現したいこと

ExcelファイルからExcelファイル(一覧)へデータを転記するプログラムを作成しました。
(複数の転記元ファイルのデータを、一覧ファイルへ転記)

転記元ファイルのAシート、Bシートの一部セル → 転記先一覧ファイルのZシート
転記元ファイルのBシートは表形式になっており、表の行数はファイルによって異なります。
Bシートに2行以上データがある場合は、Zシートにもその行数分データを転記したいのですが、
その方法がわからず、困っています。

また、Bシートの表にデータがない場合は、転記処理を行わないようにしたいのですが、
これも実現できておりません。

Aシートのデータをa、Bシート表1行目のデータをb1、2行目のデータをb2とすると、
下記のようにデータを転記するマクロを作成したいです。

転記先Zシート(C列以降にもデータを転記しますが、説明の便宜上割愛します)
' A B
1 a b1
2 a b2
3 (別ファイルも同様に繰り返す)

Bシートの表が1行のときに、転記するマクロは作成できたため、
そのソースコードを記載致しますので、アドバイスをいただきたいです。
VBA初心者のため拙いソースコードがあり、改善できる部分もありましたら、併せてご指摘をいただけますと幸いです。
わかりにくい部分もあるかと思いますが、宜しくお願い致します。

該当のソースコード

VBA

1Option Explicit 2 3Dim mFSO As FileSystemObject 4 5Sub 一覧作成() 6 Dim rngList As Range 7 Dim vrtSubjectList As Variant 8 9 'シートの非表示行を表示する 10 Cells.EntireColumn.Hidden = False 11 12 'フィルターをクリア 13 If Worksheets("一覧").FilterMode Then 14 Worksheets("一覧").ShowAllData 15 End If 16 17 '自動更新しないように設定 18 With Application 19 .ScreenUpdating = False 20 .EnableEvents = False 21 .Calculation = xlCalculationManual 22 End With 23 24 'FileSystemObjectを呼び出す 25 Set mFSO = New FileSystemObject 26 27 '一覧表のセル範囲取得 28 Set rngList = ThisWorkbook.Worksheets("一覧").Range(Cells(2, 1), Cells(Cells(Rows.Count, 3).End(xlUp).Row, Cells(2, Columns.Count).End(xlToLeft).Column)) 29 30 '一覧表クリア 31 InitializeTable rngList 32 33 'ファイルのリストを取得 34 vrtSubjectList = Get_UpdatedSubjectList(rngList) 35 36 'データの転記 37 SetUpdated vrtSubjectList, rngList 38 39 '作成した一覧表をソート 40 Sort rngList 41 42 '項番採番 43 Reference rngList 44 45 '画面描画を再開 46 With Application 47 .ScreenUpdating = True 48 .EnableEvents = True 49 .Calculation = xlCalculationAutomatic 50 End With 51 52 MsgBox "一覧表を作成しました。" 53 54End Sub 55 56'一覧表をクリア 57Private Sub InitializeTable(ByRef rngList As Range) 58 Dim rngNotBlank As Range 59 60 Set rngList = ThisWorkbook.Worksheets("一覧").Range(Cells(2, 1), Cells(Cells(Rows.Count, 3).End(xlUp).Row, Cells(2, Columns.Count).End(xlToLeft).Column)) 61 62 With rngList 63 If rngList.Rows.Count > 1 Then 64 On Error Resume Next 65 66 'C列がBlankではないセルを取得 67 Set rngList = ThisWorkbook.Worksheets("一覧").Range(Cells(3, 1), Cells(Cells(Rows.Count, 3).End(xlUp).Row, Cells(2, Columns.Count).End(xlToLeft).Column)) 68 Set rngNotBlank = rngList.Columns(3).SpecialCells(xlCellTypeConstants) 69 On Error GoTo 0 70 If rngNotBlank Is Nothing Then Exit Sub 71 72 '一覧表のデータをクリア 73 rngNotBlank.EntireRow.ClearContents 74 75 End If 76 Set rngList = rngList.CurrentRegion 77 End With 78End Sub 79 80'ファイルのフルパスのリストを取得 81Private Function Get_UpdatedSubjectList(ByRef rngList As Range) As Variant 82 Dim WSF As WorksheetFunction 83 Dim myFolder As folder 84 Dim myFile As file 85 Dim strPath As String 86 Dim vrtNewList() As Variant 87 Dim ix As Long 88 89 Dim intPos As Long 90 91 ReDim vrtNewList(1 To 50000) 92 Set WSF = Application.WorksheetFunction 93 94 strPath = ThisWorkbook.Path 95 96 '一覧と同じフォルダにあるフォルダに対して繰り返し処理 97 For Each myFolder In mFSO.GetFolder(strPath).SubFolders 98 'フォルダ内のファイルに対して繰り返し処理 99 For Each myFile In myFolder.Files 100 ix = ix + 1 101 vrtNewList(ix) = myFile.Path 102 Next 103 Next 104 105 ReDim Preserve vrtNewList(1 To ix) 106 Get_UpdatedSubjectList = vrtNewList 107End Function 108 109'データの転記 110Private Sub SetUpdated(ByVal vrtSubjectList As Variant, ByRef rngList As Range) 111 Dim f As Variant 112 Dim ix, s As Long 113 Dim rng, As Range 114 Dim vrtNewList() As Variant 115 ReDim vrtNewList(LBound(vrtSubjectList) To UBound(vrtSubjectList), 1 To 5) 116 117 For Each f In vrtSubjectList 118 ix = ix + 1 119 '更新しないでファイルを開く 120 With Workbooks.Open(f, UpdateLinks:=0, ReadOnly:=True) 121 '自動計算を有効化(正しい管理番号を取得するため) 122 With Application 123 .Calculation = xlCalculationAutomatic 124 End With 125 126 For s = 1 To Worksheets.Count 127 If Worksheets(s).Name = "B" Then 128 Worksheets("B").Activate 129 Set rng = Worksheets("B").Range(Cells(3, 2), Cells(Cells(Rows.Count, 5).End(xlUp).Row, Cells(3, Columns.Count).End(xlToLeft).Column)) 130 131 '一覧に記載があるか判定 132 If rng.Rows.Count > 1 Then 133 With .Sheets("B") 134 vrtNewList(ix, 1) = .Range("D4").Value 135 vrtNewList(ix, 3) = .Range("H4").Value 136 vrtNewList(ix, 4) = .Range("I4").Value 137 vrtNewList(ix, 5) = .Range("J4").Value 138 End With 139 With .Sheets("A") 140 vrtNewList(ix, 2) = .Range("F7").Value 141 End With 142 Next 143 End If 144 End If 145 Next 146 .Close False 147 End With 148 Next 149 150 'データを一覧に転記 151 With rngList 152 Set rngList = .Cells(3, 2).Resize(UBound(vrtNewList, 1), UBound(vrtNewList, 2)) 153 End With 154 rngList.Value = vrtNewList 155 156End Sub 157 158'作成した一覧表をソート 159Private Sub Sort(ByRef rngList As Range) 160 161 Set rngList = ThisWorkbook.Worksheets("一覧").Range(Cells(2, 1), Cells(Cells(Rows.Count, 3).End(xlUp).Row, Cells(2, Columns.Count).End(xlToLeft).Column)) 162 163 'ソート 164 With rngList 165 rngList.Sort Key1:=Range("B3"), Order1:=xlAscending, _ 166 Key2:=Range("C3"), Order2:=xlAscending, Header:=xlYes, _ 167 OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, SortMethod:=xlPinYin 168 End With 169 170End Sub 171 172'項番採番 173Private Sub Reference(ByRef rngList As Range) 174 Dim L, n As Integer 175 176 Set rngList = ThisWorkbook.Worksheets("一覧").Range(Cells(3, 1), Cells(Cells(Rows.Count, 3).End(xlUp).Row, Cells(2, Columns.Count).End(xlToLeft).Column)) 177 178 While rngList.Cells(L, 3).Value <> "" 179 rngList.Cells(L, 1).Value = n 180 L = L + 1 181 n = n + 1 182 Wend 183 184End Sub 185 186

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

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

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

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

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

kai_keitai

2020/05/29 03:38

お使いのExcelのバージョンを教えてください。 バージョンによっては、VBAを使う必要が無い可能性がある為です。
2134

2020/06/03 04:59

コメントいただきありがとうございます。 Microsoft 365 MSO 32ビット版を利用しています。 しかし、私だけが上記一覧を作成する訳ではなく、一覧を作成する人によってExcelのバージョンは異なるので、バージョンによって作成できる/できない、操作が異なることは避けたいと思っています。
guest

回答1

0

バージョンは、古い可能性があるとのことで、VBAが一番の最善の手段ですね。

ソースコードを見ると、構造化されており、それなりに経験があると思いますので、
助言をしますので、自力で解決下さい。
まず、セル範囲を取得するときに、

EXCEL

1Range(Cells(2, 1), Cells(Cells(Rows.Count, 3).End(xlUp).Row, Cells(2, Columns.Count).End(xlToLeft).Column))

と書かれているようです。
子の場合、データ件数が無い時、空白も拾ってしまい、大変なのでしょう。

実務が見えないので、解決できるかどうか不明瞭ですが、
単純にセル範囲を取得するのであれば、

EXCEL

1Set rngList = ActiveCell.CurrentRegion 2``` 3とする方法がとれます。 4Rangeオブジェクトには、Countプロパティが取得できるので、 5データ数が列数で割り算することによって、件数の取得が可能です。 6 7 8データ件数で、判断ができるのであれば、 9VBA上で、ワークシート関数で関数を取得してデータがあるのか無いのか判断もできるでしょう。 10```EXCEL VBA 11Applicatiuon.WoerksheetFunction.CountA(Rangeオブジェクト) 12``` 13これで、件数が取得できます。 14 15やり方は、自由です。 16 17ちなみに、集計担当者?が、Microsoft 365 からの Excel ProPlusであれば、VBAは不要と考えます。 18参考までに、画像のみ貼り付けします。 19![イメージ説明](5f7339de5dcfd765bfc52671909808c1.jpeg) 20本来なら、ワークシート上にテーブルを定義するのが理想です。 21さらに、データフォーマットを統一するとかポイントが必要ですが、VBAは不要だし、 22PowerQuery上で、ある程度、データの編集が可能です。

投稿2020/06/03 11:49

kai_keitai

総合スコア344

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問