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

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

新規登録して質問してみよう
ただいま回答率
85.35%
VBA

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

マクロ

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

Q&A

解決済

7回答

865閲覧

VBA マクロでの転記の実装

icecleam

総合スコア46

VBA

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

マクロ

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

0グッド

0クリップ

投稿2020/09/26 21:34

編集2020/09/27 14:34

以下の「現状のソース」を実行すると、[現状の実行結果]のようになり、「月」が正しく転記されません。

そこで、以下の「実装内容」で新たにコードを修正しようと思うのですが、コードの書き方がわからずに困っています。。。
どのようにソースを書けば良いでしょうか、ご教授いただけると幸いです。

実装内容

C列が3でセル結合しているとき.MergeCellsがTrueの時に.MergeArea.Count = 3のとき
C列に「担当者」という文字列が入っているとき、「年月」の値をコピー先の行へ設定する。

C列が2でセル結合しているとき.MergeCellsがTrueの時に.MergeArea.Count = 2のとき
C列に文字列が入っているとき、[担当者][工数]の値をコピー先の行へ設定する。


[現状のソース]

Macro

1Sub sample1() 2 3 Dim lngRowsNo As Long ' 書きこむ位置(行) 4 Dim lngSheetIndex As Long ' シートの番号 5 Dim strFile As String ' Excelファイルの場所 6 Dim xlsAcq As New Excel.Application ' 取得側Excel 7 Dim wbAcq As Workbook ' 取得側Excelブック 8 Dim wsAcq As Worksheet ' 取得側Excelシート 9 Dim wsSet As Worksheet ' 設定側Excelシート 10 Const strPath As String = "/Users/keiichi/Desktop/マクロ宿題/" 11 Set wsSet = ActiveSheet 12 Dim i As Long 13 14 strFile = Dir(strPath & "*.xls") 15 lngRowsNo = 3 ' 書きこみ開始位置(行) 16 Do Until strFile = "" 17 '----- Excelブックを開く 18 Set wbAcq = Workbooks.Open(strPath & strFile) 19 20 '----- シートを検索 21 For lngSheetIndex = 1 To wbAcq.Worksheets.Count 22 '----- 「更新」シートを検索 23 If wbAcq.Worksheets(lngSheetIndex).Name = "最新" Then 24 '----- 「更新」シートを変数へ登録 25 26 Set wsAcq = wbAcq.Worksheets(lngSheetIndex) 27 '----- 「更新」シートの内容を現在のシートにコピー(自由に変更して下さい) 28 With wsAcq 29 Dim fname As String 'ファイル名 30 Dim n As Long 'ループで使用します。 31 Dim m As Long 'ループで使用します。 32 Dim ec1 As Long '各開発の一番下の担当者のセルを取得 33 Dim ec2 As Long '各開発の 月の一番右(最後)のセルを取得 34 Dim ec3 As Long '月数を取得 35 Dim ColumnNo As Long ' 転記先の列番号(初期値4) 36 Dim ColumnNo2 As Long ' 転記元の列番号(初期値5)+3されていく 37 38 ColumnNo = 4 39 ColumnNo2 = 5 40 41 For i = 1 To .UsedRange.Rows.Count 42 43 If (Left(.Cells(i, 2).Value, 2) = "A1" Or Left(.Cells(i, 2).Value, 2) = "B1" Or Left(.Cells(i, 2).Value, 2) = "C1") And .Cells(i, 2).MergeCells = False Then 44 45 '月を取得して転記 46 ec2 = .Cells(i + 1, 5).End(xlToRight).Column + 1 47 48 For col = 5 To ec2 49 50 '「担当者」の転記 51 wsSet.Cells(lngRowsNo - 1, 3).Value = .Cells(i + 1, 3).Value 52 53 '「担当者」以降の 「月」の転記 54 wsSet.Cells(lngRowsNo - 1, ColumnNo).Value = .Cells(i + 1, ColumnNo2).Value 55 56 ColumnNo = ColumnNo + 1 57 ColumnNo2 = ColumnNo2 + 3 58 59 Next col 60 61 ' ------ 開発〇から一番上の担当者のセル位置を相対的にCells(i + 3, 3)として取得し 62 'データの入っているところまでループさせる (その時、開発名を転記) 63 ec1 = .Cells(i + 3, 2).End(xlDown).Row 64 For n = i + 3 To ec1 65 66 '担当者が空白の時スキップする 67 If Cells(n, 3) = "" Then 68 GoTo NEXT99 69 End If 70 71 'ファイル名 72 fname = ActiveWorkbook.Name 73 wsSet.Cells(lngRowsNo, 1).Value = fname 74 If .MergeArea.Count = 4 Then 75 End If 76 'メソッドまたはデータメンバーが見つかりません 77 '開発 78 wsSet.Cells(lngRowsNo, 2).Value = .Cells(i, 2).Value 79 80 '担当者 81 wsSet.Cells(lngRowsNo, 3).Value = .Cells(n, 3).Value 82 83 '工数 84 wsSet.Cells(lngRowsNo, 4).Value = .Cells(n, 5).Value 85 86 wsSet.Cells(lngRowsNo, 5).Value = .Cells(n, 8).Value 87 88 wsSet.Cells(lngRowsNo, 6).Value = .Cells(n, 11).Value 89 90 wsSet.Cells(lngRowsNo, 7).Value = .Cells(n, 14).Value 91 92 wsSet.Cells(lngRowsNo, 8).Value = .Cells(n, 17).Value 93 94 wsSet.Cells(lngRowsNo, 9).Value = .Cells(n, 20).Value 95 96 wsSet.Cells(lngRowsNo, 10).Value = .Cells(n, 23).Value 97 98 wsSet.Cells(lngRowsNo, 11).Value = .Cells(n, 26).Value 99 100 wsSet.Cells(lngRowsNo, 12).Value = .Cells(n, 29).Value 101 102 wsSet.Cells(lngRowsNo, 13).Value = .Cells(n, 32).Value 103 104 '1行下へ 105 lngRowsNo = lngRowsNo + 1 106 107NEXT99: 108 Next n 109 110 End If 111 Next i 112 End With 113 114 '----- 検索の終了 115 Exit For 116 End If 117 Next lngSheetIndex 118 119 '----- シート参照の解放 120 Set wsAcq = Nothing 121 '----- ブックを閉じる 122 wbAcq.Close Savechanges:=False 123 124 '----- 次のファイルへ 125 strFile = Dir() 126 127 128 Loop 129 130 '----- Excelへの参照の解放 131 Set xlsAcq = Nothing 132 133 Dim maxrow As Long '最終行 134 maxrow = wsSet.Cells(Rows.Count, 3).End(xlUp).Row 'C列で最終行を求める 135 For i = 3 To maxrow 136 137 If wsSet.Cells(i, "C").Value = "担当者" Then 138 wsSet.Cells(i, "A").Value = "" 139 wsSet.Cells(i, "B").Value = "" 140 End If 141 Next 142 143End Sub 144

質問2.xls
イメージ説明

質問3.xls
イメージ説明

[現状の実行結果]
イメージ説明
[実装したい実行結果]
イメージ説明

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

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

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

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

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

coco_bauer

2020/09/27 01:32

実装内容とエラーメッセージには、「.MergeArea.Count」という文字列が含まれていますが、現状のソースには含まれていません。 なので、現状のソースをコンパイルしても質問に書かれているようなエラーメッセージが出るとは思えません。 何か、取り違えをしてらっしゃいませんか?
icecleam

2020/09/27 03:33

すみません If .MergeArea.Count = 3 Then End If という1文を「現状のソース」に記載しているときに、エラーメッセージ「メソッドまたはデータメンバーが見つかりません」が出てしまいます。 質問する際にコンパイルエラーの含まれるコードを載せるのはどうかと思い、その一文は含まない形で掲載させていただきました。 すみません、確かにこの書き方だと伝わりづらいですね、、
kuma_kuma_

2020/09/27 03:36

何回も質問立ち上げないで下さい。 解説もできやしない...。解決する意思はあるのですか?
icecleam

2020/09/27 03:42 編集

すみません、、 解決する意思はあります。。 期限が決まっているため、実装する際のコードの書き方がわからずに気持ちが焦ってしまいました。。 もうこれ以上連続した質問はあげませんので、ご教授いただけないでしょうか。 何卒宜しくお願い致します。
coco_bauer

2020/09/27 03:50

伝わりづらいでところではなく、虚偽情報に付き合わされて辟易しています!
icecleam

2020/09/27 03:57

大変申し訳ありませんでした。。 次回以降、質問をさせていただく際には今回のようなことがないように気をつけます。。
guest

回答7

0

ベストアンサー

年月は偶然ですが工数とおんなじ列に値があります。
その為処理は似通ってきますが下記ソースのように記載下さい。
後調整で

  • コメントの追記
  • エラー時処理(エラーの時メッセージが表示されます)
  • 終了時の処理(Excelを使った後は必ず必要です。こう書いておく物と覚えていただけたらで構いません)

を行っています

VBA

1Public Sub sample1() 2'------------------------------------------------------------------------------- 3' sample1 4' 説明 5' コピー元のEcxelシート内[更新]シートから内容をコピーする 6' パラメータ 7' なし 8' 戻り値 9' なし 10'------------------------------------------------------------------------------- 11 12 Dim strFromXMLFileName As String ' コピー元となるExcelファイルの名前 13 Dim xlsFrom As New Excel.Application ' 取得側Excel 14 Dim wbFrom As Workbook ' 取得側Excelブック 15 Dim wsFrom As Worksheet ' 取得側Excelシート 16 Dim lngFromSheetNo As Long ' 検索するシートの番号 17 Dim lngFromRowsNo As Long ' 検索する行位置 18 19 Dim wsTo As Worksheet ' 設定側Excelシート 20 Dim lngToRowsNo As Long ' 書きこむ行位置 21 Dim varKaihatsu As Variant ' [開発]の値 22 23 Const strDefaultPath As String = "パスを指定する" 'コピー元となるExcelファイルが置いてあるフォルダのパス(\で終わる事) 24 25On Error GoTo sample1_Error: 26 27 ' コピー先の設定 28 Set wsTo = ActiveSheet ' 書きこむシートは今開いているシート 29 ' 1. コピー先の開始行は2行目から開始とする。 30 lngToRowsNo = 2 ' 書きこむ行位置2行目から 31 32 ' コピー元となるExcelファイルが置いてあるフォルダのパスからExcelファイルを検索する 33 strFromXMLFileName = Dir(strDefaultPath & "*.xls") 34 35 ' Excelファイルが見つからなくなるまで検索 36 Do Until strFromXMLFileName = "" 37 38 ' 見つかったExcelブックを開く 39 Set wbFrom = Workbooks.Open(strDefaultPath & strFromXMLFileName) 40 41 ' 見つかったExcelブックのシートを順番に検索(登録があるシートすべて) 42 For lngFromSheetNo = 1 To wbFrom.Worksheets.Count 43 44 ' シート名が"更新"のシートを検索 45 If wbFrom.Worksheets(lngFromSheetNo).Name = "更新" Then 46 47 ' コピー元のシートを設定 48 Set wsFrom = wbFrom.Worksheets(lngFromSheetNo) 49 50 ' 2. コピー元のシートを1行目から検索(登録がある行すべて) 51 For lngFromRowsNo = 1 To wsFrom.UsedRange.Rows.Count 52 53 If wsFrom.Cells(lngFromRowsNo, 3).MergeCells = True Then 54 ' C列=3 が結合セルの場合 55 Select Case wsFrom.Cells(lngFromRowsNo, 3).MergeArea.Count 56 Case 4 57 ' 4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合) 58 If wsFrom.Cells(lngFromRowsNo, 3).Value = "担当者" Then 59 ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 60 wsTo.Cells(lngToRowsNo, 3).Value = "担当者" 'C列←"担当者" 61 wsTo.Cells(lngToRowsNo, 4).Value = wsFrom.Cells(lngFromRowsNo, 5).Value 'D列←E列[年月]1 62 wsTo.Cells(lngToRowsNo, 5).Value = wsFrom.Cells(lngFromRowsNo, 8).Value 'E列←H列[年月]2 63 wsTo.Cells(lngToRowsNo, 6).Value = wsFrom.Cells(lngFromRowsNo, 11).Value 'F列←K列[年月]3 64 wsTo.Cells(lngToRowsNo, 7).Value = wsFrom.Cells(lngFromRowsNo, 14).Value 'G列←N列[年月]4 65 wsTo.Cells(lngToRowsNo, 8).Value = wsFrom.Cells(lngFromRowsNo, 17).Value 'H列←Q列[年月]5 66 wsTo.Cells(lngToRowsNo, 9).Value = wsFrom.Cells(lngFromRowsNo, 20).Value 'I列←T列[年月]6 67 wsTo.Cells(lngToRowsNo, 10).Value = wsFrom.Cells(lngFromRowsNo, 23).Value 'J列←W列[年月]7 68 wsTo.Cells(lngToRowsNo, 11).Value = wsFrom.Cells(lngFromRowsNo, 26).Value 'K列←Z列[年月]8 69 wsTo.Cells(lngToRowsNo, 12).Value = wsFrom.Cells(lngFromRowsNo, 29).Value 'L列←AC列[年月]9 70 wsTo.Cells(lngToRowsNo, 13).Value = wsFrom.Cells(lngFromRowsNo, 32).Value 'M列←AF列[年月]10 71' wsTo.Cells(lngToRowsNo, 14).Value = wsFrom.Cells(lngFromRowsNo, 35).Value 'O列←AI列[年月]11 72' wsTo.Cells(lngToRowsNo, 15).Value = wsFrom.Cells(lngFromRowsNo, 38).Value 'P列←AL列[年月]12 73 74 ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 75 lngToRowsNo = lngToRowsNo + 1 76 End If 77 78 Case 2 79 ' 5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合) 80 If IsNull(wsFrom.Cells(lngFromRowsNo, 3).Value) = False And wsFrom.Cells(lngFromRowsNo, 3).Value <> "" Then 81 ' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 82 wsTo.Cells(lngToRowsNo, 1).Value = strFromXMLFileName 'A列←ファイル名 83 wsTo.Cells(lngToRowsNo, 2).Value = varKaihatsu 'B列←開発 84 wsTo.Cells(lngToRowsNo, 3).Value = wsFrom.Cells(lngFromRowsNo, 3).Value 'C列←C列[担当者] 85 wsTo.Cells(lngToRowsNo, 4).Value = wsFrom.Cells(lngFromRowsNo, 5).Value 'D列←E列[工数]1 86 wsTo.Cells(lngToRowsNo, 5).Value = wsFrom.Cells(lngFromRowsNo, 8).Value 'E列←H列[工数]2 87 wsTo.Cells(lngToRowsNo, 6).Value = wsFrom.Cells(lngFromRowsNo, 11).Value 'F列←K列[工数]3 88 wsTo.Cells(lngToRowsNo, 7).Value = wsFrom.Cells(lngFromRowsNo, 14).Value 'G列←N列[工数]4 89 wsTo.Cells(lngToRowsNo, 8).Value = wsFrom.Cells(lngFromRowsNo, 17).Value 'H列←Q列[工数]5 90 wsTo.Cells(lngToRowsNo, 9).Value = wsFrom.Cells(lngFromRowsNo, 20).Value 'I列←T列[工数]6 91 wsTo.Cells(lngToRowsNo, 10).Value = wsFrom.Cells(lngFromRowsNo, 23).Value 'J列←W列[工数]7 92 wsTo.Cells(lngToRowsNo, 11).Value = wsFrom.Cells(lngFromRowsNo, 26).Value 'K列←Z列[工数]8 93 wsTo.Cells(lngToRowsNo, 12).Value = wsFrom.Cells(lngFromRowsNo, 29).Value 'L列←AC列[工数]9 94 wsTo.Cells(lngToRowsNo, 13).Value = wsFrom.Cells(lngFromRowsNo, 32).Value 'M列←AF列[工数]10 95' wsTo.Cells(lngToRowsNo, 14).Value = wsFrom.Cells(lngFromRowsNo, 35).Value 'O列←AI列[工数]11 96' wsTo.Cells(lngToRowsNo, 15).Value = wsFrom.Cells(lngFromRowsNo, 38).Value 'P列←AL列[工数]12 97 98 ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 99 lngToRowsNo = lngToRowsNo + 1 100 End If 101 102 End Select 103 Else 104 ' C列=3 が結合セルでない場合 105 Select Case Left(wsFrom.Cells(lngFromRowsNo, 2).Value, 2) 'B列=2 左から2文字を取得 106 Case "A1", "A2", "A3" 107 ' 3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、[開発]の値として変数に代入しておく。 108 varKaihatsu = wsFrom.Cells(lngFromRowsNo, 2).Value ' [開発]の値 109 End Select 110 End If 111 112 Next lngFromRowsNo 113 114 ' 1つのExcelファイルには同じ名前のシートが作成できないのでシート検索処理を終了する 115 Exit For 116 117 End If 118 119 Next lngFromSheetNo 120 121 ' 見つかったExcelブックを閉じる 122 Call wbFrom.Close(True) 'セーブはしない 123 Set wbFrom = Nothing '参照の解除 124 125 ' 次のExcelファイルを検索 126 strFromXMLFileName = Dir() 127 Loop 128 129sample1_End: 130On Error Resume Next 131 ' 終了処理 132 ' 取得側Excelシート 133 Set wsFrom = Nothing '参照の解除 134 ' 取得側Excelブック 135 Call wbFrom.Close(True) 'セーブはしない 136 Set wbFrom = Nothing '参照の解除 137 ' 取得側Excel 138 xlsFrom.Quit 'Excelを閉じる 139 Set xlsFrom = Nothing '参照の解除 140Exit Sub 141 142'----- エラー処理 143sample1_Error: 144 Call MsgBox("ErrNo:" & Err & vbNewLine & Error, vbOKOnly + vbCritical, "sample1") 145Resume sample1_End: 146End Sub 147 148 149

投稿2020/09/27 14:43

kuma_kuma_

総合スコア2506

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

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

icecleam

2020/09/27 14:49

上記のコードで実装できました。。 本当に長い時間お付き合いいただきありがとうございました。。 また何かあったら、よろしくお願いします
kuma_kuma_

2020/09/27 14:56

お疲れ様です。 注意しておきますが ここはあくまで「わからない事に対して答える場」であって 「作成依頼」する場ではありません。 また「無料の家庭教師」の場でもありません。 よって最低限質問者様が動かないと返答できません。 今回ここまでしたのは夜中まで作業されて何度も質問されている様子から 最低限質問者様が努力している(投げっぱなしではない)と判断したからです。(特例とお考えください。)
icecleam

2020/09/27 15:09

はい、本当にありがとうございました なんども心が折れそうでしたが、最後まで根気よくお付き合いいただき 本当に助かりました。
guest

0

質問者様この今の状態が大切なのです

  • 質問者様はやりたい処理が明確になっている。
  • きちんと清書した動くコードがある。
  • 不明点(セルの結合がいくつか?)が明確である。

この状態で質問していただけたら回答はすぐにつきます。

下に質問の参考例を記載します。

エクセルのシート間の値のコピー処理で
一部どうやって判断したらよいかわからず困っています。

実現したいこと

このような手順で処理を行っていこうと考えています。

1行目 B列値が入力されていない。C列結合なし。
→無処理
...
13行目 B列値が入力されていない。C列結合なし。
→無処理

14行目 B列に"A1"が記載
→[開発]の値として変数に代入する

15行目 C列に「担当者」が記載
→4セル結合で"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。
16行目 C列に「担当者」が記載
→4セル結合だがC列には値が入っていないので無処理

17~28行目 C列に各担当者が記載(空白の際はスキップ)
→2セル結合なのでC列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。
29~31行目
→3セル結合なので無処理

32行目 B列C列にB1が記載
→[開発]の値として変数に代入する

33 C列に「担当者」が記載
→4セル結合で"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。
34行目 C列D列に「担当者」が記載
→4セル結合だがC列には値が入っていないので無処理

...
以降繰り返し

困っている事

ただ上記にある「セルの結合」の判断をどうしたら行えるかが判りません。
もしセルの結合以外で判断できるならたの方法でもかましません。

現在まで完成しているコード

VBA

1Public Sub sample1() 2'------------------------------------------------------------------------------- 3' sample1 4' 説明 5' コピー元のEcxelシート内[更新]シートから内容をコピーする 6' パラメータ 7' なし 8' 戻り値 9' なし 10'------------------------------------------------------------------------------- 11 12 Dim strFromXMLFileName As String ' コピー元となるExcelファイルの名前 13 Dim xlsFrom As New Excel.Application ' 取得側Excel 14 Dim wbFrom As Workbook ' 取得側Excelブック 15 Dim wsFrom As Worksheet ' 取得側Excelシート 16 Dim lngFromSheetNo As Long ' 検索するシートの番号 17 Dim lngFromRowsNo As Long ' 検索する行位置 18 19 Dim wsTo As Worksheet ' 設定側Excelシート 20 Dim lngToRowsNo As Long ' 書きこむ行位置 21 Dim varKaihatsu As Variant ' [開発]の値 22 23 Const strDefaultPath As String = "パスを指定する" 'コピー元となるExcelファイルが置いてあるフォルダのパス(\で終わる事) 24 25On Error GoTo sample1_Error: 26 27 ' コピー先の設定 28 Set wsTo = ActiveSheet ' 書きこむシートは今開いているシート 29 ' 1. コピー先の開始行は2行目から開始とする。 30 lngToRowsNo = 2 ' 書きこむ行位置2行目から 31 32 ' コピー元となるExcelファイルが置いてあるフォルダのパスからExcelファイルを検索する 33 strFromXMLFileName = Dir(strDefaultPath & "*.xls") 34 35 ' Excelファイルが見つからなくなるまで検索 36 Do Until strFromXMLFileName = "" 37 38 ' 見つかったExcelブックを開く 39 Set wbFrom = Workbooks.Open(strDefaultPath & strFromXMLFileName) 40 41 ' 見つかったExcelブックのシートを順番に検索(登録があるシートすべて) 42 For lngFromSheetNo = 1 To wbFrom.Worksheets.Count 43 44 ' シート名が"更新"のシートを検索 45 If wbFrom.Worksheets(lngFromSheetNo).Name = "更新" Then 46 47 ' コピー元のシートを設定 48 Set wsFrom = wbFrom.Worksheets(lngFromSheetNo) 49 50 ' 2. コピー元のシートを1行目から検索(登録がある行すべて) 51 For lngFromRowsNo = 1 To wsFrom.UsedRange.Rows.Count 52 Select Case Left(wsFrom.Cells(lngFromRowsNo, 2).Value) 'B列=2 左から2文字を取得 53 Case "A1", "A2", "A3" 54 ' 3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、[開発]の値として変数に代入しておく。 55 varKaihatsu = wsFrom.Cells(lngFromRowsNo, 2).Value ' [開発]の値 56 End Select 57 58 ' 4. C列が4セル結合している場合 59 60 ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 61 62 ' 5. C列が2セル結合している場合 63 64 ' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 65 66 Next lngFromRowsNo 67 68 ' 1つのExcelファイルには同じ名前のシートが作成できないのでシート検索処理を終了する 69 Exit For 70 71 End If 72 73 Next lngFromSheetNo 74 75 ' 見つかったExcelブックを閉じる 76 Call wbFrom.Close(True) 'セーブはしない 77 Set wbFrom = Nothing '参照の解除 78 79 ' 次のExcelファイルを検索 80 strFromXMLFileName = Dir() 81 Loop 82 83sample1_End: 84On Error Resume Next 85Exit Sub 86 87'----- エラー処理 88sample1_Error: 89Resume sample1_End: 90End Sub 91

投稿2020/09/27 09:32

編集2020/09/27 11:40
kuma_kuma_

総合スコア2506

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

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

kuma_kuma_

2020/09/27 09:34

質問の例までやっとたどり着きましたのでその後の回答を別に記載します。
icecleam

2020/09/27 09:37

質問をするにも、前準備が大切なのですね。 今後の参考にさせて頂きます。 ありがとうございます ご回答お待ちしています…
guest

0

質問に対して回答します。
まず「セル結合」に関しては".MergeCells"がtrueかで判定できます。
この場合

VBA

1If wsFrom.Cells(lngFromRowsNo, 3).MergeCells = True Then

このような書き方となります。
また「セル結合」に関しては".MergeArea.Count"で確認することができます。

VBA

1Select Case wsFrom.Cells(lngFromRowsNo, 3).MergeArea.Count

一応".MergeCells"で判定後IF文を分けて".MergeArea.Count"を検索下さい
(エラーになる可能性があります)

あと質問者様のソースで2点ばかり気になった点があったので修正してみました
1点目. B列に"A1"or"B1"or"C1"で始まる文字列がある場合
参考資料を拝見すると15行目以降にも値が入っているご様子。
条件にC列が結合されていない場合を追加しました。

2点目. "Select Case " 文をご存じな様に見受けられました。
これは繰り返しIFをかかなくてても良い書き方となります。
コードが見やすくなるかと思い修正しました。

確認のほどよろしくお願いします。

追記
「セル結合」した場合例として"A1:B2"の4セル結合の場合、値が取得できるのは左上の"A1"が含まれている時のみとなります。("A2","B1","B2"では取得できない)

VBA

1Public Sub sample1() 2'------------------------------------------------------------------------------- 3' sample1 4' 説明 5' コピー元のEcxelシート内[更新]シートから内容をコピーする 6' パラメータ 7' なし 8' 戻り値 9' なし 10'------------------------------------------------------------------------------- 11 12 Dim strFromXMLFileName As String ' コピー元となるExcelファイルの名前 13 Dim xlsFrom As New Excel.Application ' 取得側Excel 14 Dim wbFrom As Workbook ' 取得側Excelブック 15 Dim wsFrom As Worksheet ' 取得側Excelシート 16 Dim lngFromSheetNo As Long ' 検索するシートの番号 17 Dim lngFromRowsNo As Long ' 検索する行位置 18 19 Dim wsTo As Worksheet ' 設定側Excelシート 20 Dim lngToRowsNo As Long ' 書きこむ行位置 21 Dim varKaihatsu As Variant ' [開発]の値 22 23 Const strDefaultPath As String = "パスを指定する" 'コピー元となるExcelファイルが置いてあるフォルダのパス(\で終わる事) 24 25On Error GoTo sample1_Error: 26 27 ' コピー先の設定 28 Set wsTo = ActiveSheet ' 書きこむシートは今開いているシート 29 ' 1. コピー先の開始行は2行目から開始とする。 30 lngToRowsNo = 2 ' 書きこむ行位置2行目から 31 32 ' コピー元となるExcelファイルが置いてあるフォルダのパスからExcelファイルを検索する 33 strFromXMLFileName = Dir(strDefaultPath & "*.xls") 34 35 ' Excelファイルが見つからなくなるまで検索 36 Do Until strFromXMLFileName = "" 37 38 ' 見つかったExcelブックを開く 39 Set wbFrom = Workbooks.Open(strDefaultPath & strFromXMLFileName) 40 41 ' 見つかったExcelブックのシートを順番に検索(登録があるシートすべて) 42 For lngFromSheetNo = 1 To wbFrom.Worksheets.Count 43 44 ' シート名が"更新"のシートを検索 45 If wbFrom.Worksheets(lngFromSheetNo).Name = "更新" Then 46 47 ' コピー元のシートを設定 48 Set wsFrom = wbFrom.Worksheets(lngFromSheetNo) 49 50 ' 2. コピー元のシートを1行目から検索(登録がある行すべて) 51 For lngFromRowsNo = 1 To wsFrom.UsedRange.Rows.Count 52 53 ' C列=3 が結合セルの場合 54 If wsFrom.Cells(lngFromRowsNo, 3).MergeCells = True Then 55 Select Case wsFrom.Cells(lngFromRowsNo, 3).MergeArea.Count 56 Case 4 57 ' 4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合) 58 If wsFrom.Cells(lngFromRowsNo, 3).Value = "担当者" Then 59 ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 60 61 ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 62 lngToRowsNo = lngToRowsNo + 1 63 End If 64 65 Case 2 66 ' 5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合) 67 If IsNull(wsFrom.Cells(lngFromRowsNo, 3).Value) = False And wsFrom.Cells(lngFromRowsNo, 3).Value <> "" Then 68 ' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 69 70 ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 71 lngToRowsNo = lngToRowsNo + 1 72 End If 73 End Select 74 Else 75 Select Case Left(wsFrom.Cells(lngFromRowsNo, 2).Value, 2) 'B列=2 左から2文字を取得 76 Case "A1", "A2", "A3" 77 ' 3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、[開発]の値として変数に代入しておく。 78 varKaihatsu = wsFrom.Cells(lngFromRowsNo, 2).Value ' [開発]の値 79 End Select 80 End If 81 82 Next lngFromRowsNo 83 84 ' 1つのExcelファイルには同じ名前のシートが作成できないのでシート検索処理を終了する 85 Exit For 86 87 End If 88 89 Next lngFromSheetNo 90 91 ' 見つかったExcelブックを閉じる 92 Call wbFrom.Close(True) 'セーブはしない 93 Set wbFrom = Nothing '参照の解除 94 95 ' 次のExcelファイルを検索 96 strFromXMLFileName = Dir() 97 Loop 98 99sample1_End: 100On Error Resume Next 101Exit Sub 102 103'----- エラー処理 104sample1_Error: 105Resume sample1_End: 106End Sub

投稿2020/09/27 09:45

編集2020/09/27 10:07
kuma_kuma_

総合スコア2506

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

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

kuma_kuma_

2020/09/27 09:50

実は私の手順でエラーになりそうな要素をわざと残していました。 (回答の1点目.)これが「盲目的に回答を信じてはいけない」理由です。 あと先で書かれた実行手順は修正をかけて正確なものとしています。 これはもともと質問者様が知らない情報なので先の回答になってもしょうがない事です。(追記忘れてましたので書いておきます。)
kuma_kuma_

2020/09/27 09:56

あとはどこの列の値をどこにコピーすればよいか記載するだけです。 答えは質問者様の前のコードに書いてあります。
icecleam

2020/09/27 09:58

上記の件、承知致しました。 Select Case Left(wsFrom.Cells(lngFromRowsNo, 2).Value) 'B列=2 左から2文字を取得 この行でエラーメッセージ「引数は省略できません」と出てしまうのですが 動作確認をそちらでされた際には正常に動きましたでしょうか。。 また、その部分をコメントアウトして実行したところ、転記先に何も転記されませんでした。。
kuma_kuma_

2020/09/27 10:03

失礼しました。回答修正しておきました > Select Case Left(wsFrom.Cells(lngFromRowsNo, 2).Value, 2) 'B列=2 左 ちなみに上に書いていますが後 あとはどこの列の値をどこにコピーすればよいか記載する作業が残っていますよ?
icecleam

2020/09/27 10:31

なんどもなんども本当にすみません 今、質問の現状のソースを更新したのですが 上記のソースだと、エラーはないのですが質問用2のエクセルファイルを開いたところで処理が止まってしまい、もちろん何も転記はされません、、 どこの列の値をどこにコピーすればよいかというところも差し支えなければ教えていただきたいです。。 以下の箇所を追記しました ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 wsSet.Cells(lngRowsNo, 3).Value = wsFrom.Cells(lngFromRowsNo, 3).Value
kuma_kuma_

2020/09/27 10:37 編集

だからwsSetって変数ないでしょ! 今回wsToって変数に変更したでしょ? あとlngRowsNoもlngToRowsNoでしょ?
kuma_kuma_

2020/09/27 10:40

というか > どこの列の値をどこにコピーすればよいかというところも差し支えなければ教えていただきたいです。。 一応これ書かない事で「やってほしいことだけを記載した丸投げの質問」から回避する言い訳にしてるんだけど...
icecleam

2020/09/27 11:15 編集

すみません、上記の修正した現状のソースのように修正したら無事に現状の実行結果のように実行できました。 ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 wsTo.Cells(lngToRowsNo, 3).Value = ありがとうございます 「担当者」の部分はご指摘のおかげで、実装できました! しかし、以下の部分がどう頑張ってもうまく実装できません。。 最後の最後にすみませんが、ここまで教えていただけないでしょうか。。 ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。
kuma_kuma_

2020/09/27 11:36 編集

ん?質問のコード直しちゃった(現状のソース)? そっちは直しちゃだめだよ新しいコードは内容の追記にしないと (他の人が後で見たら?になるでしょ) で今できているソースは?
icecleam

2020/09/27 11:40

すみません、質問を修正しました。 現状できているソースは以下になります。[追記、修正後のソース] 実行結果は[現状の実行結果]になります。 申し訳ありません、よろしくお願いします [追記、修正後のソース] ```Macro Public Sub sample1() '------------------------------------------------------------------------------- ' sample1 ' 説明 ' コピー元のEcxelシート内[更新]シートから内容をコピーする ' パラメータ ' なし ' 戻り値 ' なし '------------------------------------------------------------------------------- Dim strFromXMLFileName As String ' コピー元となるExcelファイルの名前 Dim xlsFrom As New Excel.Application ' 取得側Excel Dim wbFrom As Workbook ' 取得側Excelブック Dim wsFrom As Worksheet ' 取得側Excelシート Dim lngFromSheetNo As Long ' 検索するシートの番号 Dim lngFromRowsNo As Long ' 検索する行位置 Dim wsTo As Worksheet ' 設定側Excelシート Dim lngToRowsNo As Long ' 書きこむ行位置 Dim varKaihatsu As Variant ' [開発]の値 Const strDefaultPath As String = "指定パス" 'コピー元となるExcelファイルが置いてあるフォルダのパス(\で終わる事) On Error GoTo sample1_Error: ' コピー先の設定 Set wsTo = ActiveSheet ' 書きこむシートは今開いているシート ' 1. コピー先の開始行は2行目から開始とする。 lngToRowsNo = 2 ' 書きこむ行位置2行目から ' コピー元となるExcelファイルが置いてあるフォルダのパスからExcelファイルを検索する strFromXMLFileName = Dir(strDefaultPath & "*.xls") ' Excelファイルが見つからなくなるまで検索 Do Until strFromXMLFileName = "" ' 見つかったExcelブックを開く Set wbFrom = Workbooks.Open(strDefaultPath & strFromXMLFileName) ' 見つかったExcelブックのシートを順番に検索(登録があるシートすべて) For lngFromSheetNo = 1 To wbFrom.Worksheets.Count ' シート名が"更新"のシートを検索 If wbFrom.Worksheets(lngFromSheetNo).Name = "更新" Then ' コピー元のシートを設定 Set wsFrom = wbFrom.Worksheets(lngFromSheetNo) ' 2. コピー元のシートを1行目から検索(登録がある行すべて) For lngFromRowsNo = 1 To wsFrom.UsedRange.Rows.Count ' C列=3 が結合セルの場合 If wsFrom.Cells(lngFromRowsNo, 3).MergeCells = True Then Select Case wsFrom.Cells(lngFromRowsNo, 3).MergeArea.Count Case 4 ' 4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合) If wsFrom.Cells(lngFromRowsNo, 3).Value = "担当者" Then ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 wsTo.Cells(lngToRowsNo, 3).Value = wsFrom.Cells(lngFromRowsNo, 3).Value ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 lngToRowsNo = lngToRowsNo + 1 End If Case 2 ' 5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合) If IsNull(wsFrom.Cells(lngFromRowsNo, 3).Value) = False And wsFrom.Cells(lngFromRowsNo, 3).Value <> "" Then ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 lngToRowsNo = lngToRowsNo + 1 End If End Select Else Select Case Left(wsFrom.Cells(lngFromRowsNo, 2).Value, 2) 'B列=2 左から2文字を取得 Case "A1", "A2", "A3" ' 3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、[開発]の値として変数に代入しておく。 varKaihatsu = wsFrom.Cells(lngFromRowsNo, 2).Value ' [開発]の値 End Select End If Next lngFromRowsNo ' 1つのExcelファイルには同じ名前のシートが作成できないのでシート検索処理を終了する Exit For End If Next lngFromSheetNo ' 見つかったExcelブックを閉じる Call wbFrom.Close(True) 'セーブはしない Set wbFrom = Nothing '参照の解除 ' 次のExcelファイルを検索 strFromXMLFileName = Dir() Loop sample1_End: On Error Resume Next Exit Sub '----- エラー処理 sample1_Error: Resume sample1_End: End Sub ```
kuma_kuma_

2020/09/27 11:44 編集

いや「質問」に「現状のソース」はそのままに追記として 新たに「指摘をうけ修正したソース」とかで書いてほしかったんです... でソース確認したけど1処理しか書いてないけれど他はどうしたんですか?
icecleam

2020/09/27 11:46

すみません、追記しようとしてたら文字数制限を超えてしまい、追記できなかったのでこちらで書かせていただきました。。 1処理しかというのはどういうことでしょうか?
icecleam

2020/09/27 11:47

' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 ↑の部分のソースの書き方を教えていただきたいのです。。
kuma_kuma_

2020/09/27 11:49

文字数制限の件了解しました。 >1処理しかというのはどういうことでしょうか? 先の私の回答から wsTo.Cells(lngToRowsNo, 3).Value = wsFrom.Cells(lngFromRowsNo, 3).Value だけしか追加になっていませんよね? 残りの[年月]の設定と 明細行の時の設定が全く書かれていなのですが...
kuma_kuma_

2020/09/27 11:51

> ↑の部分のソースの書き方を教えていただきたいのです。。 その前に明細終わらせましょうよ...。
icecleam

2020/09/27 12:23

すみません、、、 また気持ちが先走ってしまいました。。 また、以下のように明細行部分を実装しようとしましたが、また質問用2のファイルを開いたところで止まってしまいました。。 すみません、また確認をお願いします。。 ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 wsTo.Cells(lngToRowsNo, 3).Value = wsFrom.Cells(lngFromRowsNo, 3).Value ec2 = wsFrom.Cells(i + 1, 5).End(xlToRight).Column + 1 For col = 5 To ec2 wsTo.Cells(lngToRowsNo, ColumnNo).Value = wbFrom.Cells(lngFromRowsNo + 1, ColumnNo2).Value ColumnNo = ColumnNo + 1 ColumnNo2 = ColumnNo2 + 3 Next col
kuma_kuma_

2020/09/27 12:29

だから明細を先に終わらせましょう。 ていうか、こんな処理はじめに提示されていた[現状のソース]にないですよね? [現状のソース]と同じ書き方でいいんですからそれを書いてください。
kuma_kuma_

2020/09/27 12:37

確認します。どこにも書かれていないのですが、”年月”は何か月分あるのですか?ソースコード上からは10か月としか読み取れないのですが...。
icecleam

2020/09/27 12:39

すみません、「明細」というのは担当者のA,B,C・・のことでしょうか?
icecleam

2020/09/27 12:42

>確認します。どこにも書かれていないのですが、”年月”は何か月分あるので>すか?ソースコード上からは10か月としか読み取れないのですが...。 そうですね、現状は10ヶ月分で作成を進めていますので、それで問題ありません
kuma_kuma_

2020/09/27 12:43

?処理確認しましたよね? ' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 ここの処理です。
icecleam

2020/09/27 13:13 編集

すみません、なぜかコピーペーストをしたはずなのですが回答の内容とコードが異なっている部分があり、 ' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 が見当たらず勘違いをしてしまいました。 現在の回答の最新のソースで再度修正をかけたのですが、やはり質問用2のファイルが開くだけで終わってしまいます。。 ソース Public Sub sample1() '------------------------------------------------------------------------------- ' sample1 ' 説明 ' コピー元のEcxelシート内[更新]シートから内容をコピーする ' パラメータ ' なし ' 戻り値 ' なし '------------------------------------------------------------------------------- Dim strFromXMLFileName As String ' コピー元となるExcelファイルの名前 Dim xlsFrom As New Excel.Application ' 取得側Excel Dim wbFrom As Workbook ' 取得側Excelブック Dim wsFrom As Worksheet ' 取得側Excelシート Dim lngFromSheetNo As Long ' 検索するシートの番号 Dim lngFromRowsNo As Long ' 検索する行位置 Dim wsTo As Worksheet ' 設定側Excelシート Dim lngToRowsNo As Long ' 書きこむ行位置 Dim varKaihatsu As Variant ' [開発]の値 Dim ColumnNo As Long ' 転記先の列番号(初期値4) Dim ColumnNo2 As Long ' 転記元の列番号(初期値5)+3されていく Const strDefaultPath As String = "パス" 'コピー元となるExcelファイルが置いてあるフォルダのパス(\で終わる事) On Error GoTo sample1_Error: ' コピー先の設定 Set wsTo = ActiveSheet ' 書きこむシートは今開いているシート ' 1. コピー先の開始行は2行目から開始とする。 lngToRowsNo = 2 ' 書きこむ行位置2行目から ' コピー元となるExcelファイルが置いてあるフォルダのパスからExcelファイルを検索する strFromXMLFileName = Dir(strDefaultPath & "*.xls") ' Excelファイルが見つからなくなるまで検索 Do Until strFromXMLFileName = "" ' 見つかったExcelブックを開く Set wbFrom = Workbooks.Open(strDefaultPath & strFromXMLFileName) ' 見つかったExcelブックのシートを順番に検索(登録があるシートすべて) For lngFromSheetNo = 1 To wbFrom.Worksheets.Count ' シート名が"更新"のシートを検索 If wbFrom.Worksheets(lngFromSheetNo).Name = "更新" Then ' コピー元のシートを設定 Set wsFrom = wbFrom.Worksheets(lngFromSheetNo) ' 2. コピー元のシートを1行目から検索(登録がある行すべて) For lngFromRowsNo = 1 To wsFrom.UsedRange.Rows.Count ' C列=3 が結合セルの場合 If wsFrom.Cells(lngFromRowsNo, 3).MergeCells = True Then Select Case wsFrom.Cells(lngFromRowsNo, 3).MergeArea.Count Case 4 ' 4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合) If wsFrom.Cells(lngFromRowsNo, 3).Value = "担当者" Then ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 wsTo.Cells(lngToRowsNo, 3).Value = wsFrom.Cells(lngFromRowsNo, 3).Value If wsFrom.Cells(lngFromRowsNo, 3).Value = "担当者" Then ec2 = wsFrom.Cells(i + 1, 5).End(xlToRight).Column + 1 For col = 5 To ec2 wsTo.Cells(lngToRowsNo, ColumnNo).Value = wbFrom.Cells(lngFromRowsNo + 1, ColumnNo2).Value ColumnNo = ColumnNo + 1 ColumnNo2 = ColumnNo2 + 3 Next col End If ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 lngToRowsNo = lngToRowsNo + 1 End If Case 2 ' 5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合) If IsNull(wsFrom.Cells(lngFromRowsNo, 3).Value) = False And wsFrom.Cells(lngFromRowsNo, 3).Value <> "" Then ' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 If IsNull(wsTo.Cells(lngToRowsNo, 3).Value) = True Then wsSet.Cells(lngRowsNo, 4).Value = wsFrom.Cells(lngFromRowsNo + 3, 5).Value wsSet.Cells(lngRowsNo, 5).Value = wsFrom.Cells(lngFromRowsNo + 3, 8).Value wsSet.Cells(lngRowsNo, 6).Value = wsFrom.Cells(lngFromRowsNo + 3, 11).Value wsSet.Cells(lngRowsNo, 7).Value = wsFrom.Cells(lngFromRowsNo + 3, 14).Value wsSet.Cells(lngRowsNo, 8).Value = wsFrom.Cells(lngFromRowsNo + 3, 17).Value wsSet.Cells(lngRowsNo, 9).Value = wsFrom.Cells(lngFromRowsNo + 3, 20).Value wsSet.Cells(lngRowsNo, 10).Value = wsFrom.Cells(lngFromRowsNo + 3, 23).Value wsSet.Cells(lngRowsNo, 11).Value = wsFrom.Cells(lngFromRowsNo + 3, 26).Value wsSet.Cells(lngRowsNo, 12).Value = wsFrom.Cells(lngFromRowsNo + 3, 29).Value wsSet.Cells(lngRowsNo, 13).Value = wsFrom.Cells(lngFromRowsNo + 3, 32).Value End If ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 lngToRowsNo = lngToRowsNo + 1 End If End Select Else Select Case Left(wsFrom.Cells(lngFromRowsNo, 2).Value, 2) 'B列=2 左から2文字を取得 Case "A1", "A2", "A3" ' 3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、[開発]の値として変数に代入しておく。 varKaihatsu = wsFrom.Cells(lngFromRowsNo, 2).Value ' [開発]の値 End Select End If Next lngFromRowsNo ' 1つのExcelファイルには同じ名前のシートが作成できないのでシート検索処理を終了する Exit For End If Next lngFromSheetNo ' 見つかったExcelブックを閉じる Call wbFrom.Close(True) 'セーブはしない Set wbFrom = Nothing '参照の解除 ' 次のExcelファイルを検索 strFromXMLFileName = Dir() Loop sample1_End: On Error Resume Next Exit Sub '----- エラー処理 sample1_Error: Resume sample1_End: End Sub
kuma_kuma_

2020/09/27 13:16

そりゃそうだ > If IsNull(wsTo.Cells(lngToRowsNo, 3).Value) = True Then なんでこんな余計な処理入れているの? これじゃ前に判定した"文字が入っているとき"と真逆の判定だよね?
icecleam

2020/09/27 13:20

すみません、処理を勘違いしていましたので以下のように修正しました。 修正後も挙動が変わりませんでした。。 If IsNull(wsTo.Cells(lngToRowsNo, 3).Value) = False Then
kuma_kuma_

2020/09/27 13:23

> wsSet.Cells(lngRowsNo, 4).Value あとまた同じ間違い wsSetもlngRowsNoも違うでしょ!
kuma_kuma_

2020/09/27 13:24

> If IsNull(wsTo.Cells(lngToRowsNo, 3).Value) = False Then だからこの判定自体いらないと書いているでしょ? なんで追加してるの?どんどん意味不明な方向になってますよ!
kuma_kuma_

2020/09/27 13:30

ちゃんと確認して ' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 の上に If IsNull(wsFrom.Cells(lngFromRowsNo, 3).Value) = False And wsFrom.Cells(lngFromRowsNo, 3).Value <> "" Then って条件書いてあるでしょ?これはC列に文字列が入っていますよ!っていう判定。
icecleam

2020/09/27 13:33 編集

ごめんなさい、、 以下のように修正したのですが、まだ同じ挙動でした。。 ご迷惑でなければ回答を教えていただけないでしょうか。。。 ソース --- Public Sub sample1() '------------------------------------------------------------------------------- ' sample1 ' 説明 ' コピー元のEcxelシート内[更新]シートから内容をコピーする ' パラメータ ' なし ' 戻り値 ' なし '------------------------------------------------------------------------------- Dim strFromXMLFileName As String ' コピー元となるExcelファイルの名前 Dim xlsFrom As New Excel.Application ' 取得側Excel Dim wbFrom As Workbook ' 取得側Excelブック Dim wsFrom As Worksheet ' 取得側Excelシート Dim lngFromSheetNo As Long ' 検索するシートの番号 Dim lngFromRowsNo As Long ' 検索する行位置 Dim wsTo As Worksheet ' 設定側Excelシート Dim lngToRowsNo As Long ' 書きこむ行位置 Dim varKaihatsu As Variant ' [開発]の値 Dim ColumnNo As Long ' 転記先の列番号(初期値4) Dim ColumnNo2 As Long ' 転記元の列番号(初期値5)+3されていく Const strDefaultPath As String = "" 'コピー元となるExcelファイルが置いてあるフォルダのパス(\で終わる事) On Error GoTo sample1_Error: ' コピー先の設定 Set wsTo = ActiveSheet ' 書きこむシートは今開いているシート ' 1. コピー先の開始行は2行目から開始とする。 lngToRowsNo = 2 ' 書きこむ行位置2行目から ' コピー元となるExcelファイルが置いてあるフォルダのパスからExcelファイルを検索する strFromXMLFileName = Dir(strDefaultPath & "*.xls") ' Excelファイルが見つからなくなるまで検索 Do Until strFromXMLFileName = "" ' 見つかったExcelブックを開く Set wbFrom = Workbooks.Open(strDefaultPath & strFromXMLFileName) ' 見つかったExcelブックのシートを順番に検索(登録があるシートすべて) For lngFromSheetNo = 1 To wbFrom.Worksheets.Count ' シート名が"更新"のシートを検索 If wbFrom.Worksheets(lngFromSheetNo).Name = "更新" Then ' コピー元のシートを設定 Set wsFrom = wbFrom.Worksheets(lngFromSheetNo) ' 2. コピー元のシートを1行目から検索(登録がある行すべて) For lngFromRowsNo = 1 To wsFrom.UsedRange.Rows.Count ' C列=3 が結合セルの場合 If wsFrom.Cells(lngFromRowsNo, 3).MergeCells = True Then Select Case wsFrom.Cells(lngFromRowsNo, 3).MergeArea.Count Case 4 ' 4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合) If wsFrom.Cells(lngFromRowsNo, 3).Value = "担当者" Then ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 wsTo.Cells(lngToRowsNo, 3).Value = wsFrom.Cells(lngFromRowsNo, 3).Value If wsFrom.Cells(lngFromRowsNo, 3).Value = "担当者" Then ec2 = wsFrom.Cells(i + 1, 5).End(xlToRight).Column + 1 For col = 5 To ec2 wsTo.Cells(lngToRowsNo, ColumnNo).Value = wbFrom.Cells(lngFromRowsNo + 1, ColumnNo2).Value ColumnNo = ColumnNo + 1 ColumnNo2 = ColumnNo2 + 3 Next col End If ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 lngToRowsNo = lngToRowsNo + 1 End If Case 2 ' 5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合) If IsNull(wsFrom.Cells(lngFromRowsNo, 3).Value) = False And wsFrom.Cells(lngFromRowsNo, 3).Value <> "" Then ' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 wsTo.Cells(lngToRowsNo, 4).Value = wsFrom.Cells(lngFromRowsNo + 3, 5).Value wsTo.Cells(lngToRowsNo, 5).Value = wsFrom.Cells(lngFromRowsNo + 3, 8).Value wsTo.Cells(lngToRowsNo, 6).Value = wsFrom.Cells(lngFromRowsNo + 3, 11).Value wsTo.Cells(lngToRowsNo, 7).Value = wsFrom.Cells(lngFromRowsNo + 3, 14).Value wsTo.Cells(lngToRowsNo, 8).Value = wsFrom.Cells(lngFromRowsNo + 3, 17).Value wsTo.Cells(lngToRowsNo, 9).Value = wsFrom.Cells(lngFromRowsNo + 3, 20).Value wsTo.Cells(lngToRowsNo, 10).Value = wsFrom.Cells(lngFromRowsNo + 3, 23).Value wsTo.Cells(lngToRowsNo, 11).Value = wsFrom.Cells(lngFromRowsNo + 3, 26).Value wsTo.Cells(lngToRowsNo, 12).Value = wsFrom.Cells(lngFromRowsNo + 3, 29).Value wsTo.Cells(lngToRowsNo, 13).Value = wsFrom.Cells(lngFromRowsNo + 3, 32).Value ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 lngToRowsNo = lngToRowsNo + 1 End If End Select Else Select Case Left(wsFrom.Cells(lngFromRowsNo, 2).Value, 2) 'B列=2 左から2文字を取得 Case "A1", "A2", "A3" ' 3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、[開発]の値として変数に代入しておく。 varKaihatsu = wsFrom.Cells(lngFromRowsNo, 2).Value ' [開発]の値 End Select End If Next lngFromRowsNo ' 1つのExcelファイルには同じ名前のシートが作成できないのでシート検索処理を終了する Exit For End If Next lngFromSheetNo ' 見つかったExcelブックを閉じる Call wbFrom.Close(True) 'セーブはしない Set wbFrom = Nothing '参照の解除 ' 次のExcelファイルを検索 strFromXMLFileName = Dir() Loop sample1_End: On Error Resume Next Exit Sub '----- エラー処理 sample1_Error: Resume sample1_End: End Sub
kuma_kuma_

2020/09/27 13:33

だから質問者様が書かれた If IsNull(wsTo.Cells(lngToRowsNo, 3).Value) = False Then ていう83行目と対になる106行目End Ifがいらないから削除してといっています。
icecleam

2020/09/27 13:34

すみません、編集後に気づいて その箇所を修正しました ソースは先ほどのものと同様です
kuma_kuma_

2020/09/27 13:40

まず ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 に書いてある余計な処理消して 次に[現状のソース] と同じなのに > wsTo.Cells(lngToRowsNo, 4).Value = wsFrom.Cells(lngFromRowsNo + 3, 5).Value なんで余計な処理増やすの? > wsTo.Cells(lngToRowsNo, 4).Value = wsFrom.Cells(lngFromRowsNo, 5).Value そのまま書いたらこうでしょ?なんで行に3足すの?
icecleam

2020/09/27 13:46

本当に申し訳ありませんでした 行と列を間違えていました。。 例えば A1から列に3を足したセルに最初の年月があるので、それで設定していました。。
kuma_kuma_

2020/09/27 13:49 編集

ずっと書いているんですが余計な事をぜず[現状のソース] と同じように書いてください。 それで済むように準備してきてるんですから! (なにも足したりしないで下さい。)
icecleam

2020/09/27 13:51

はい。。 ありがとうございます 今現在のソースは以下のようになっていますが、相変わらず質問用2のファイルが開くだけです。。 Public Sub sample1() '------------------------------------------------------------------------------- ' sample1 ' 説明 ' コピー元のEcxelシート内[更新]シートから内容をコピーする ' パラメータ ' なし ' 戻り値 ' なし '------------------------------------------------------------------------------- Dim strFromXMLFileName As String ' コピー元となるExcelファイルの名前 Dim xlsFrom As New Excel.Application ' 取得側Excel Dim wbFrom As Workbook ' 取得側Excelブック Dim wsFrom As Worksheet ' 取得側Excelシート Dim lngFromSheetNo As Long ' 検索するシートの番号 Dim lngFromRowsNo As Long ' 検索する行位置 Dim wsTo As Worksheet ' 設定側Excelシート Dim lngToRowsNo As Long ' 書きこむ行位置 Dim varKaihatsu As Variant ' [開発]の値 Dim ColumnNo As Long ' 転記先の列番号(初期値4) Dim ColumnNo2 As Long ' 転記元の列番号(初期値5)+3されていく Const strDefaultPath As String = "" 'コピー元となるExcelファイルが置いてあるフォルダのパス(\で終わる事) On Error GoTo sample1_Error: ' コピー先の設定 Set wsTo = ActiveSheet ' 書きこむシートは今開いているシート ' 1. コピー先の開始行は2行目から開始とする。 lngToRowsNo = 2 ' 書きこむ行位置2行目から ' コピー元となるExcelファイルが置いてあるフォルダのパスからExcelファイルを検索する strFromXMLFileName = Dir(strDefaultPath & "*.xls") ' Excelファイルが見つからなくなるまで検索 Do Until strFromXMLFileName = "" ' 見つかったExcelブックを開く Set wbFrom = Workbooks.Open(strDefaultPath & strFromXMLFileName) ' 見つかったExcelブックのシートを順番に検索(登録があるシートすべて) For lngFromSheetNo = 1 To wbFrom.Worksheets.Count ' シート名が"更新"のシートを検索 If wbFrom.Worksheets(lngFromSheetNo).Name = "更新" Then ' コピー元のシートを設定 Set wsFrom = wbFrom.Worksheets(lngFromSheetNo) ' 2. コピー元のシートを1行目から検索(登録がある行すべて) For lngFromRowsNo = 1 To wsFrom.UsedRange.Rows.Count ' C列=3 が結合セルの場合 If wsFrom.Cells(lngFromRowsNo, 3).MergeCells = True Then Select Case wsFrom.Cells(lngFromRowsNo, 3).MergeArea.Count Case 4 ' 4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合) If wsFrom.Cells(lngFromRowsNo, 3).Value = "担当者" Then ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 wsTo.Cells(lngToRowsNo, 3).Value = wsFrom.Cells(lngFromRowsNo, 3).Value If wsFrom.Cells(lngFromRowsNo, 3).Value = "担当者" Then ec2 = wsFrom.Cells(i + 1, 5).End(xlToRight).Column + 1 For col = 5 To ec2 wsTo.Cells(lngToRowsNo, ColumnNo).Value = wbFrom.Cells(lngFromRowsNo + 1, ColumnNo2).Value ColumnNo = ColumnNo + 1 ColumnNo2 = ColumnNo2 + 3 Next col End If ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 lngToRowsNo = lngToRowsNo + 1 End If Case 2 ' 5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合) If IsNull(wsFrom.Cells(lngFromRowsNo, 3).Value) = False And wsFrom.Cells(lngFromRowsNo, 3).Value <> "" Then ' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 wsTo.Cells(lngToRowsNo, 4).Value = wsFrom.Cells(lngFromRowsNo, 5).Value wsTo.Cells(lngToRowsNo, 5).Value = wsFrom.Cells(lngFromRowsNo, 8).Value wsTo.Cells(lngToRowsNo, 6).Value = wsFrom.Cells(lngFromRowsNo, 11).Value wsTo.Cells(lngToRowsNo, 7).Value = wsFrom.Cells(lngFromRowsNo, 14).Value wsTo.Cells(lngToRowsNo, 8).Value = wsFrom.Cells(lngFromRowsNo, 17).Value wsTo.Cells(lngToRowsNo, 9).Value = wsFrom.Cells(lngFromRowsNo, 20).Value wsTo.Cells(lngToRowsNo, 10).Value = wsFrom.Cells(lngFromRowsNo, 23).Value wsTo.Cells(lngToRowsNo, 11).Value = wsFrom.Cells(lngFromRowsNo, 26).Value wsTo.Cells(lngToRowsNo, 12).Value = wsFrom.Cells(lngFromRowsNo, 29).Value wsTo.Cells(lngToRowsNo, 13).Value = wsFrom.Cells(lngFromRowsNo, 32).Value ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 lngToRowsNo = lngToRowsNo + 1 End If End Select Else Select Case Left(wsFrom.Cells(lngFromRowsNo, 2).Value, 2) 'B列=2 左から2文字を取得 Case "A1", "A2", "A3" ' 3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、[開発]の値として変数に代入しておく。 varKaihatsu = wsFrom.Cells(lngFromRowsNo, 2).Value ' [開発]の値 End Select End If Next lngFromRowsNo ' 1つのExcelファイルには同じ名前のシートが作成できないのでシート検索処理を終了する Exit For End If Next lngFromSheetNo ' 見つかったExcelブックを閉じる Call wbFrom.Close(True) 'セーブはしない Set wbFrom = Nothing '参照の解除 ' 次のExcelファイルを検索 strFromXMLFileName = Dir() Loop sample1_End: On Error Resume Next Exit Sub '----- エラー処理 sample1_Error: Resume sample1_End: End Sub
kuma_kuma_

2020/09/27 13:56

だから65行目から74行目、77行目もいらないから消して!
icecleam

2020/09/27 14:04

本当にすみません、、、 エラーメッセージ 「Select Case に対応する Case がありません。」 というのが出てしまいました。。 繰り返し何度もすみません。。。 ソースは以下です Public Sub sample1() '------------------------------------------------------------------------------- ' sample1 ' 説明 ' コピー元のEcxelシート内[更新]シートから内容をコピーする ' パラメータ ' なし ' 戻り値 ' なし '------------------------------------------------------------------------------- Dim strFromXMLFileName As String ' コピー元となるExcelファイルの名前 Dim xlsFrom As New Excel.Application ' 取得側Excel Dim wbFrom As Workbook ' 取得側Excelブック Dim wsFrom As Worksheet ' 取得側Excelシート Dim lngFromSheetNo As Long ' 検索するシートの番号 Dim lngFromRowsNo As Long ' 検索する行位置 Dim wsTo As Worksheet ' 設定側Excelシート Dim lngToRowsNo As Long ' 書きこむ行位置 Dim varKaihatsu As Variant ' [開発]の値 Dim ColumnNo As Long ' 転記先の列番号(初期値4) Dim ColumnNo2 As Long ' 転記元の列番号(初期値5)+3されていく Const strDefaultPath As String = "" 'コピー元となるExcelファイルが置いてあるフォルダのパス(\で終わる事) On Error GoTo sample1_Error: ' コピー先の設定 Set wsTo = ActiveSheet ' 書きこむシートは今開いているシート ' 1. コピー先の開始行は2行目から開始とする。 lngToRowsNo = 2 ' 書きこむ行位置2行目から ' コピー元となるExcelファイルが置いてあるフォルダのパスからExcelファイルを検索する strFromXMLFileName = Dir(strDefaultPath & "*.xls") ' Excelファイルが見つからなくなるまで検索 Do Until strFromXMLFileName = "" ' 見つかったExcelブックを開く Set wbFrom = Workbooks.Open(strDefaultPath & strFromXMLFileName) ' 見つかったExcelブックのシートを順番に検索(登録があるシートすべて) For lngFromSheetNo = 1 To wbFrom.Worksheets.Count ' シート名が"更新"のシートを検索 If wbFrom.Worksheets(lngFromSheetNo).Name = "更新" Then ' コピー元のシートを設定 Set wsFrom = wbFrom.Worksheets(lngFromSheetNo) ' 2. コピー元のシートを1行目から検索(登録がある行すべて) For lngFromRowsNo = 1 To wsFrom.UsedRange.Rows.Count ' C列=3 が結合セルの場合 If wsFrom.Cells(lngFromRowsNo, 3).MergeCells = True Then Select Case wsFrom.Cells(lngFromRowsNo, 3).MergeArea.Count Case 4 ' 4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合) If wsFrom.Cells(lngFromRowsNo, 3).Value = "担当者" Then ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 wsTo.Cells(lngToRowsNo, 3).Value = wsFrom.Cells(lngFromRowsNo, 3).Value ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 lngToRowsNo = lngToRowsNo + 1 Case 2 ' 5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合) If IsNull(wsFrom.Cells(lngFromRowsNo, 3).Value) = False And wsFrom.Cells(lngFromRowsNo, 3).Value <> "" Then ' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 wsTo.Cells(lngToRowsNo, 4).Value = wsFrom.Cells(lngFromRowsNo, 5).Value wsTo.Cells(lngToRowsNo, 5).Value = wsFrom.Cells(lngFromRowsNo, 8).Value wsTo.Cells(lngToRowsNo, 6).Value = wsFrom.Cells(lngFromRowsNo, 11).Value wsTo.Cells(lngToRowsNo, 7).Value = wsFrom.Cells(lngFromRowsNo, 14).Value wsTo.Cells(lngToRowsNo, 8).Value = wsFrom.Cells(lngFromRowsNo, 17).Value wsTo.Cells(lngToRowsNo, 9).Value = wsFrom.Cells(lngFromRowsNo, 20).Value wsTo.Cells(lngToRowsNo, 10).Value = wsFrom.Cells(lngFromRowsNo, 23).Value wsTo.Cells(lngToRowsNo, 11).Value = wsFrom.Cells(lngFromRowsNo, 26).Value wsTo.Cells(lngToRowsNo, 12).Value = wsFrom.Cells(lngFromRowsNo, 29).Value wsTo.Cells(lngToRowsNo, 13).Value = wsFrom.Cells(lngFromRowsNo, 32).Value ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 lngToRowsNo = lngToRowsNo + 1 End If End Select Else Select Case Left(wsFrom.Cells(lngFromRowsNo, 2).Value, 2) 'B列=2 左から2文字を取得 Case "A1", "A2", "A3" ' 3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、[開発]の値として変数に代入しておく。 varKaihatsu = wsFrom.Cells(lngFromRowsNo, 2).Value ' [開発]の値 End Select End If Next lngFromRowsNo ' 1つのExcelファイルには同じ名前のシートが作成できないのでシート検索処理を終了する Exit For End If Next lngFromSheetNo ' 見つかったExcelブックを閉じる Call wbFrom.Close(True) 'セーブはしない Set wbFrom = Nothing '参照の解除 ' 次のExcelファイルを検索 strFromXMLFileName = Dir() Loop sample1_End: On Error Resume Next Exit Sub '----- エラー処理 sample1_Error: Resume sample1_End: End Sub
icecleam

2020/09/27 14:04

エラーが出ているのはcase2のところです
kuma_kuma_

2020/09/27 14:05

消したら最後から2番目 Resume sample1_End: にブレークポイント設定して実行してみて
kuma_kuma_

2020/09/27 14:06

> エラーが出ているのはcase2のところです どんなエラー?
icecleam

2020/09/27 14:11

>どんなエラー? エラーメッセージ 「Select Case に対応する Case がありません。」 これのことでした ブレークポイントを打って見ます
icecleam

2020/09/27 14:12

すみません、コンパイルエラーですのでブレークポイントを打っても実行できないです。。
kuma_kuma_

2020/09/27 14:13

いや構文エラーだから... 作業で壊しちゃっていますね原型を...
kuma_kuma_

2020/09/27 14:14

もうさすがに時間切れです。
icecleam

2020/09/27 14:16

>もうさすがに時間切れです。 ご回答はいただけないということでしょうか・・
kuma_kuma_

2020/09/27 14:25

いや答えはもう何度も提示しているんですが、なぜ余計な処理を増やしたり するのですか?2~3分で済むところもう4時間以上やっていますよ。 質問者様はなにがしたいのですか? 1. ここで回答で書いた内容をそのままコピー 2. [現状のソース]の 77行目 '開発から 166 行目の ... = .Cells(n, 32).Valueまでを ' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 の下にコピー 3. 変数名の略称や名称が変わっているので書き直す これだけお願いしているのですが、できませんか?
kuma_kuma_

2020/09/27 14:28

最低限な事はしていだだかないと「やってほしいことだけを記載した丸投げの質問」に抵触してこちらも答える事ができないからお願いしているのです。
icecleam

2020/09/27 14:33

すみません、今上記のことを見直し最初から実装し直したら年月の箇所以外はうまく動いてくれました。。 ごめんなさい、最後のお願いです、 年月の転記はここからどのように修正すれば良いでしょうか。。 ソースは以下になります Public Sub sample1() '------------------------------------------------------------------------------- ' sample1 ' 説明 ' コピー元のEcxelシート内[更新]シートから内容をコピーする ' パラメータ ' なし ' 戻り値 ' なし '------------------------------------------------------------------------------- Dim strFromXMLFileName As String ' コピー元となるExcelファイルの名前 Dim xlsFrom As New Excel.Application ' 取得側Excel Dim wbFrom As Workbook ' 取得側Excelブック Dim wsFrom As Worksheet ' 取得側Excelシート Dim lngFromSheetNo As Long ' 検索するシートの番号 Dim lngFromRowsNo As Long ' 検索する行位置 Dim wsTo As Worksheet ' 設定側Excelシート Dim lngToRowsNo As Long ' 書きこむ行位置 Dim varKaihatsu As Variant ' [開発]の値 Const strDefaultPath As String = "/Users/keiichi/Desktop/マクロ宿題/" 'コピー元となるExcelファイルが置いてあるフォルダのパス(\で終わる事) On Error GoTo sample1_Error: ' コピー先の設定 Set wsTo = ActiveSheet ' 書きこむシートは今開いているシート ' 1. コピー先の開始行は2行目から開始とする。 lngToRowsNo = 2 ' 書きこむ行位置2行目から ' コピー元となるExcelファイルが置いてあるフォルダのパスからExcelファイルを検索する strFromXMLFileName = Dir(strDefaultPath & "*.xls") ' Excelファイルが見つからなくなるまで検索 Do Until strFromXMLFileName = "" ' 見つかったExcelブックを開く Set wbFrom = Workbooks.Open(strDefaultPath & strFromXMLFileName) ' 見つかったExcelブックのシートを順番に検索(登録があるシートすべて) For lngFromSheetNo = 1 To wbFrom.Worksheets.Count ' シート名が"更新"のシートを検索 If wbFrom.Worksheets(lngFromSheetNo).Name = "更新" Then ' コピー元のシートを設定 Set wsFrom = wbFrom.Worksheets(lngFromSheetNo) ' 2. コピー元のシートを1行目から検索(登録がある行すべて) For lngFromRowsNo = 1 To wsFrom.UsedRange.Rows.Count ' C列=3 が結合セルの場合 If wsFrom.Cells(lngFromRowsNo, 3).MergeCells = True Then Select Case wsFrom.Cells(lngFromRowsNo, 3).MergeArea.Count Case 4 ' 4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合) If wsFrom.Cells(lngFromRowsNo, 3).Value = "担当者" Then ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 wsTo.Cells(lngToRowsNo, 3).Value = wsFrom.Cells(lngFromRowsNo, 3).Value ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 lngToRowsNo = lngToRowsNo + 1 End If Case 2 ' 5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合) If IsNull(wsFrom.Cells(lngFromRowsNo, 3).Value) = False And wsFrom.Cells(lngFromRowsNo, 3).Value <> "" Then ' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 strFromXMLFileName = ActiveWorkbook.Name wsTo.Cells(lngToRowsNo, 1).Value = strFromXMLFileName '開発 wsTo.Cells(lngToRowsNo, 2).Value = wsFrom.Cells(lngFromRowsNo, 2).Value '担当者 wsTo.Cells(lngToRowsNo, 3).Value = wsFrom.Cells(lngFromRowsNo, 3).Value wsTo.Cells(lngToRowsNo, 4).Value = wsFrom.Cells(lngFromRowsNo, 5).Value wsTo.Cells(lngToRowsNo, 5).Value = wsFrom.Cells(lngFromRowsNo, 8).Value wsTo.Cells(lngToRowsNo, 6).Value = wsFrom.Cells(lngFromRowsNo, 11).Value wsTo.Cells(lngToRowsNo, 7).Value = wsFrom.Cells(lngFromRowsNo, 14).Value wsTo.Cells(lngToRowsNo, 8).Value = wsFrom.Cells(lngFromRowsNo, 17).Value wsTo.Cells(lngToRowsNo, 9).Value = wsFrom.Cells(lngFromRowsNo, 20).Value wsTo.Cells(lngToRowsNo, 10).Value = wsFrom.Cells(lngFromRowsNo, 23).Value wsTo.Cells(lngToRowsNo, 11).Value = wsFrom.Cells(lngFromRowsNo, 26).Value wsTo.Cells(lngToRowsNo, 12).Value = wsFrom.Cells(lngFromRowsNo, 29).Value wsTo.Cells(lngToRowsNo, 13).Value = wsFrom.Cells(lngFromRowsNo, 32).Value ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 lngToRowsNo = lngToRowsNo + 1 End If End Select Else Select Case Left(wsFrom.Cells(lngFromRowsNo, 2).Value, 2) 'B列=2 左から2文字を取得 Case "A1", "A2", "A3" ' 3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、[開発]の値として変数に代入しておく。 varKaihatsu = wsFrom.Cells(lngFromRowsNo, 2).Value ' [開発]の値 End Select End If Next lngFromRowsNo ' 1つのExcelファイルには同じ名前のシートが作成できないのでシート検索処理を終了する Exit For End If Next lngFromSheetNo ' 見つかったExcelブックを閉じる Call wbFrom.Close(True) 'セーブはしない Set wbFrom = Nothing '参照の解除 ' 次のExcelファイルを検索 strFromXMLFileName = Dir() Loop sample1_End: On Error Resume Next Exit Sub '----- エラー処理 sample1_Error: Resume sample1_End: End Sub
icecleam

2020/09/27 14:35

追記 実行結果は質問の現状の結果のようになっています(編集済み)
kuma_kuma_

2020/09/27 14:38

ここまで書いていただけたら更なる回答ができます。 別に回答を用意します。
icecleam

2020/09/27 14:43

すみません、本当に助かります。。
guest

0

先の回答と同じ内容です。
現在できている部分は○を付けておきます。
これは私が導きだした手順です。
質問者様はこの内容が「私が回答」したから盲目的に正しいと思っていませんか?もしかして間違っているかもしれません。

コピー元シートを1行目から検索していってどう判定さていくか書き出してみてください。
例 13行目までは書いておきます。
1行目 B列C列に値が入力されていない
→無処理
...
13行目 B列C列に値が入力されていない
→無処理

○_1. コピー先の開始行は2行目から開始とする。

○_2. コピー元のシートを1行目から検索
○_3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、[開発]の値として変数に代入しておく。

_4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合)

__4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。

_5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合)

__5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。

○※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動

投稿2020/09/27 08:14

kuma_kuma_

総合スコア2506

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

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

icecleam

2020/09/27 08:24

ご回答ありがとうございます 確かに盲目的になっていたところがあるかもしれません、そこは確認させていただきます。 質問内容にも記載しているのですが、以下に該当する部分の実装部分のソースの書き方がわからない、という内容が最初の質問でしたが、そこは結局教えていただくことはできないのでしょうか。。 _4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合) __4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 _5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合) __5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。
icecleam

2020/09/27 08:26

また、 >例 13行目までは書いておきます。 この13行目というのはどの段階でのソースのことを言っているのでしょうか。。
kuma_kuma_

2020/09/27 08:28 編集

だから慌てない!手順を踏んでいるんだから ここまで来て最後答えを教えないなんてしないから! それとも学習する気がないのですか?
icecleam

2020/09/27 08:30 編集

ごめんなさい。。 期限が明日の朝ということもあり、気持ちが焦ってました。。 学習する気はあります。 引き続きお付き合いください。。
kuma_kuma_

2020/09/27 08:31

大丈夫ここまでくればあと少しだから!
kuma_kuma_

2020/09/27 08:34

これは質問者様の意図と私が考えた意図が同じか確認するための大事な作業です。ここで違うとプログラムに直しても結果が思った通りになりません。
icecleam

2020/09/27 08:35

ありがとうございます。。! あ、すみません >例 13行目までは書いておきます。 この13行目というのはどの段階でのソースのことを言っているのでしょうか。。 こちらの質問のご回答をいただいてもよろしいでしょうか。。
kuma_kuma_

2020/09/27 08:43

今回ですと「質問2.xls」の[更新]シートを(コピー元)を上の1行目から検索していってどうなるか?で構いません。 >どの段階でのソース ではなくここで「回答」した内容があるでしょ? これで14行目はどうなるのか?15行目は?16行目は?と書いてほしいのです。長いので33行目までとしましょうか。 それで本当に処理として正しいのか質問者様が判断するのです。
icecleam

2020/09/27 09:00

お待たせいたしました。 以下のように記載しました。 ご確認のほど、よろしくお願いします 14行目 B列C列にA1が記載 →開発]の値として変数に代入する 15、16行目 C列D列に「担当者」が記載 →4セル結合で"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 17〜31行目 C列D列に各担当者が記載(空白の際はスキップ) 2セル結合でC列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 32行目 B列C列にB1が記載 →開発]の値として変数に代入する 33、34行目 C列D列に「担当者」が記載 →4セル結合で"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。
kuma_kuma_

2020/09/27 09:05

はい。これで質問者様が意図する動きになりましたか?
icecleam

2020/09/27 09:10

はい、これが私の動かしたい内容になります。 >これで質問者様が意図する動きになりましたか? まだソースの作成は行なっていないので、マクロを実行してこの動きには当然ですがなりません。
kuma_kuma_

2020/09/27 09:15

> まだソースの作成は行なっていないので、マクロを実行してこの動きには当然ですがなりません。 慌てないで下さい。この動きをすれば値が取得できますよね? この値の検索方法(判断方法)は質問者様の意図する動きと一緒ですか? という意味です。 これで問題なければそのままVBAに変換するだけですから。
kuma_kuma_

2020/09/27 09:16

また新たに回答に記載します。
icecleam

2020/09/27 09:18

はい、問題ありません。 最終的には質問の画像の[実装したい実行結果]のようにしたいので、もしわかりづらいところなどあればそちらも参考にしていただけると幸いです、
guest

0

先ほどの回答と同じ内容です
※変数名がlngFromSheetIndexだと適切ではないでlngFromSheetNoに変更だけしています。

コメントで
'***** ここから
'***** ここまで
と書かれている箇所が今回私が回答した内容です。
一部に関してはいままで質問者様が書かれてたソースコードで書くことができます。
書けないところはコメントのままで良いのでVBAに変換できる箇所を
ここの部分だけで構いませんので返答下さい。

VBA

1Public Sub sample1() 2'------------------------------------------------------------------------------- 3' sample1 4' 説明 5' コピー元のEcxelシート内[更新]シートから内容をコピーする 6' パラメータ 7' なし 8' 戻り値 9' なし 10'------------------------------------------------------------------------------- 11 12 Dim strFromXMLFileName As String ' コピー元となるExcelファイルの名前 13 Dim xlsFrom As New Excel.Application ' 取得側Excel 14 Dim wbFrom As Workbook ' 取得側Excelブック 15 Dim wsFrom As Worksheet ' 取得側Excelシート 16 Dim lngFromSheetNo As Long ' 検索するシートの番号 17 Dim lngFromRowsNo As Long ' 検索する行位置 18 19 Dim wsTo As Worksheet ' 設定側Excelシート 20 Dim lngToRowsNo As Long ' 書きこむ行位置 21 22 Const strDefaultPath As String = "パスを指定する" 'コピー元となるExcelファイルが置いてあるフォルダのパス(\で終わる事) 23 24On Error GoTo sample1_Error: 25 26 ' コピー先の設定 27 Set wsTo = ActiveSheet ' 書きこむシートは今開いているシート 28 ' 1. コピー先の開始行は2行目から開始とする。 29 lngToRowsNo = 2 ' 書きこむ行位置2行目から 30 31 ' コピー元となるExcelファイルが置いてあるフォルダのパスからExcelファイルを検索する 32 strFromXMLFileName = Dir(strDefaultPath & "*.xls") 33 34 ' Excelファイルが見つからなくなるまで検索 35 Do Until strFromXMLFileName = "" 36 37 ' 見つかったExcelブックを開く 38 Set wbFrom = Workbooks.Open(strDefaultPath & strFromXMLFileName) 39 40 ' 2. コピー元のシートを1行目から検索 41 ' 見つかったExcelブックのシートを順番に検索(登録があるシートすべて) 42 For lngFromSheetNo = 1 To wbFrom.Worksheets.Count 43 44 ' シート名が"更新"のシートを検索 45 If wbFrom.Worksheets(lngFromSheetNo).Name = "更新" Then 46 47 ' コピー元のシートを設定 48 Set wsFrom = wbFrom.Worksheets(lngFromSheetNo) 49 50 '***** ここから 51 ' 2. コピー元のシートを1行目から検索 52 53 ' 3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、[開発]の値として変数に代入しておく。 54 55 ' 4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合) 56 57 ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 58 59 ' 5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合) 60 61 ' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 62 63 ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 64 '***** ここまで 65 66 End If 67 68 Next lngFromSheetNo 69 70 ' 見つかったExcelブックを閉じる 71 Call wbFrom.Close(True) 'セーブはしない 72 Set wbFrom = Nothing '参照の解除 73 74 ' 次のExcelファイルを検索 75 strFromXMLFileName = Dir() 76 Loop 77 78sample1_End: 79On Error Resume Next 80Exit Sub 81 82'----- エラー処理 83sample1_Error: 84Resume sample1_End: 85End Sub

追記1
質問者様の返答内容を記載します。
(追記・編集依頼ですと表示が崩れる為)

VBA

1'***** ここから 2' 2. コピー元のシートを1行目から検索 3For lngFromSheetIndex = 1 To .UsedRange.Rows.Count 4'※なぜlngFromSheetIndexなのですか?変数は用意していますよね? 5'※.UsedRange.Rows.Countに関いて省略して書かない。 6 7' 3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、またはセルが結合されていない場合、[開発]の値として変数に代入しておく。 8If (Left(.Cells(i, 2).Value, 2) = "A1" Or Left(.Cells(i, 2).Value, 2) = "B1" Or Left(.Cells(i, 2).Value, 2) = "C1") And .Cells(i, 2).MergeCells = False Then 9'※セルの参照でなぜi変数を使っているのですか? 10'ただ不要な条件があります。 11 12End If 13' 4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合) 14 15' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 16 17' 5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合) 18 19' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 20 21' コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 22lngRowsNo = lngRowsNo + 1 23' ※なぜlngRowsNoなのですか?変数は用意済みですよね? 24Next i 25 26'***** ここまで 27

追記2
質問者様の返答内容を記載します。

VBA

1'***** ここから 2' 2. コピー元のシートを1行目から検索 3For lngFromRowsNo = 1 To .UsedRange.Rows.Count 4'※.UsedRange.Rows.Countは省略しない!直っていません 5 6' 3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、[開発]の値として変数に代入しておく。 7If (Left(.Cells(lngFromRowsNo, 2).Value, 2) = "A1" Or Left(.Cells(lngFromRowsNo, 2).Value, 2) = "B1" Or Left(.Cells(lngFromRowsNo, 2).Value, 2) = "C1") Then 8'訂正.Cells( は省略しない 9 10End If 11' 4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合) 12 13' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 14 15' 5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合) 16 17' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 18 19' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 20lngRowsNo = lngRowsNo + 1 21'※ここもなぜ変数lngRowsNoなんですか?直っていません 22 23Next i 24'※追加 ここの変数名もおかしいですよね? 25 26'***** ここまで

投稿2020/09/27 06:24

編集2020/09/27 07:34
kuma_kuma_

総合スコア2506

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

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

icecleam

2020/09/27 06:48

以下のようになりました。 コメント3に関しては少しだけ変更をしています。 後のところは、昨晩考えてもわからなかった箇所になります。。 また、以下の修正内容でなぜか 「参照が無効、または不完全です」というエラーが出てしまいます。。(コメント2のUsedRange) 重ね重ねで申し訳ありませんが、ソースをどう書けば良いのか、教えていただきたいです。 '***** ここから ' 2. コピー元のシートを1行目から検索 For lngFromSheetIndex = 1 To .UsedRange.Rows.Count ' 3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、またはセルが結合されていない場合、[開発]の値として変数に代入しておく。 If (Left(.Cells(i, 2).Value, 2) = "A1" Or Left(.Cells(i, 2).Value, 2) = "B1" Or Left(.Cells(i, 2).Value, 2) = "C1") And .Cells(i, 2).MergeCells = False Then End If ' 4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合) ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 ' 5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合) ' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 lngRowsNo = lngRowsNo + 1 Next i '***** ここまで End If Next lngFromSheetIndex
kuma_kuma_

2020/09/27 07:02 編集

追記1で回答しましたが、これじゃ先の清書で書いた意味がないじゃないですか?再度直してください
kuma_kuma_

2020/09/27 07:06

すみません再度確認したところ訂正点が増えています。 再度確認後修正して下さい。
icecleam

2020/09/27 07:11 編集

すみません、再度見直しました(結果は以下に記載) 疑問を投げかけられている部分は修正しております。 見直したのですが「.UsedRange.Rows.Count」というのが省略された形という認識がそもそもありませんでした。(インターネットでも少し調べたのですがわかりませんでした。。) そこの記載も教えていただけないでしょうか。。 知識が少なく。。すみません。。 '***** ここから ' 2. コピー元のシートを1行目から検索 For lngFromRowsNo = 1 To .UsedRange.Rows.Count ' 3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、[開発]の値として変数に代入しておく。 If (Left(.Cells(lngFromRowsNo, 2).Value, 2) = "A1" Or Left(.Cells(lngFromRowsNo, 2).Value, 2) = "B1" Or Left(.Cells(lngFromRowsNo, 2).Value, 2) = "C1") Then End If ' 4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合) ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 ' 5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合) ' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 lngRowsNo = lngRowsNo + 1 Next i '***** ここまで End If Next lngFromRowsNo
icecleam

2020/09/27 07:11

>すみません再度確認したところ訂正点が増えています。 >再度確認後修正して下さい。 再度回答を編集しました
kuma_kuma_

2020/09/27 07:17

そこは編集じゃなくって新たに書いて でないと前と後どこが変わったかわからないでしょ?
kuma_kuma_

2020/09/27 07:22

確認しましたがまだ直っていいない箇所があります。 (新たに1か所間違いがありました) 再度返信下さい
icecleam

2020/09/27 07:23

追記1に対する回答(kuma_kuma_さんが16:06に追記したものに対するもの含む)を記載しましたという意味でした 私が15:48に編集したものはそれ以降編集していません
kuma_kuma_

2020/09/27 07:26 編集

> 私が15:48に編集したものはそれ以降編集していません 失礼しました。これは私の勘違いでした。 ただ誤りに関しては変更ありません。
icecleam

2020/09/27 07:26

見直したのですが「.UsedRange.Rows.Count」というのが省略された形という認識がそもそもありませんでした。(インターネットでも少し調べたのですがわかりませんでした。。) そこの記載も教えていただけないでしょうか。。 知識が少なく。。すみません。。 ↑ こちらに対する回答もいただけないでしょうか。。。
kuma_kuma_

2020/09/27 07:32

".UsedRange"の"."が付いているでしょ? これはその前に"With "で変数を指定しておいてその変数から略してかいてあります。 今回"With "で変数指定してないでしょ? なれている人なら"With "は便利だけれども初心者は間違いの元だから 今回清書ではずしてあるんです。 このままじゃコンパイルエラーになるでしょう! ちゃんとどこの値かを認識する意味でも慣れないうちは"With "を使わない。
kuma_kuma_

2020/09/27 07:35

すみませんセルの所でも省略形で書かれていましたね そこも修正して下さい。
icecleam

2020/09/27 07:46

本当にすみません、書き方がわからないです。。。 以下のように書いてもエラーが出てしまいます。 ここだけ教えていただくことは可能でしょうか。。 For lngFromRowsNo = 1 To .Cells(With(.Cells(lngFromRowsNo, 2).Rows.Count)
kuma_kuma_

2020/09/27 07:55 編集

だから他人のコードをコピペするだけだからこんな問題が発生するんです。 せめて清書していたらすぐに判るのに... 質問者様の元のソース29行目 With wsAcq って書いていますよね そうするとこの"With "~"End With"の範囲では省略形でかくことができました。 本来 wsAcq.UsedRange.Rows.Count と書く所が省略形で書けるので .UsedRange.Rows.Count と書けていたのです 同じく本来 wsAcq.cells(i, 2) と書く所が省略形で書けるので .cells(i, 2) と書けていたのです これで理解できますか?
icecleam

2020/09/27 08:04

ありがとうございます。ようやく理解することができました 修正したソースは以下になります。 ご確認宜しくお願いします。 '***** ここから ' 2. コピー元のシートを1行目から検索 For lngFromRowsNo = 1 To wsFrom.UsedRange.Rows.Count ' 3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、[開発]の値として変数に代入しておく。 If wsFrom.Cells((Left(wsFrom.Cells(lngFromRowsNo, 2).Value, 2) = "A1" Or Left(wsFrom.Cells(lngFromRowsNo, 2).Value, 2) = "B1" Or Left(wsFrom.Cells(lngFromRowsNo, 2).Value, 2) = "C1")) Then End If ' 4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合) ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 ' 5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合) ' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 lngToRowsNo = lngToRowsNo + 1 Next lngFromRowsNo '***** ここまで End If Next lngFromSheetNo
kuma_kuma_

2020/09/27 08:07

はい。ここまでは大丈夫そうですね。 それでは一度おさらいをします。 なんで?と思われるかもしれませんが最後に重要だとわかるのでお付き合いください。
icecleam

2020/09/27 08:08

ご確認いただきありがとうございます。 理解が追いつかないところがあり、不快な思いをさせてしまい申し訳ありませんでした。
guest

0

まずは質問者者様が書かれていた先で説明する以前の内容を清書しました。
コメントだらけになりますが、この様に初めははやりたい処理を日本語で書いて
それに合わせてコードを書き足します。

まずは処理自体は変わっていませんので以前の内容と比べてみてみて下さい。
(※エラートラップだけ追加しています)

VBA

1Public Sub sample1() 2'------------------------------------------------------------------------------- 3' sample1 4' 説明 5' コピー元のEcxelシート内[更新]シートから内容をコピーする 6' パラメータ 7' なし 8' 戻り値 9' なし 10'------------------------------------------------------------------------------- 11 12 Dim strFromXMLFileName As String ' コピー元となるExcelファイルの名前 13 Dim xlsFrom As New Excel.Application ' 取得側Excel 14 Dim wbFrom As Workbook ' 取得側Excelブック 15 Dim wsFrom As Worksheet ' 取得側Excelシート 16 Dim lngFromSheetIndex As Long ' 検索するシートの番号 17 Dim lngFromRowsNo As Long ' 検索する行位置 18 19 Dim wsTo As Worksheet ' 設定側Excelシート 20 Dim lngToRowsNo As Long ' 書きこむ行位置 21 22 Const strDefaultPath As String = "パスを指定する" 'コピー元となるExcelファイルが置いてあるフォルダのパス(\で終わる事) 23 24On Error GoTo sample1_Error: 25 26 ' コピー先の設定 27 Set wsTo = ActiveSheet ' 書きこむシートは今開いているシート 28 ' 1. コピー先の開始行は2行目から開始とする。 29 lngToRowsNo = 2 ' 書きこむ行位置2行目から 30 31 ' コピー元となるExcelファイルが置いてあるフォルダのパスからExcelファイルを検索する 32 strFromXMLFileName = Dir(strDefaultPath & "*.xls") 33 34 ' Excelファイルが見つからなくなるまで検索 35 Do Until strFromXMLFileName = "" 36 37 ' 見つかったExcelブックを開く 38 Set wbFrom = Workbooks.Open(strDefaultPath & strFromXMLFileName) 39 40 41 ' 見つかったExcelブックのシートを順番に検索 42 For lngFromSheetIndex = 1 To wbFrom.Worksheets.Count 43 44 ' シート名が"更新"のシートを検索 45 If wbFrom.Worksheets(lngFromSheetIndex).Name = "更新" Then 46 47 ' コピー元のシートを設定 48 Set wsFrom = wbFrom.Worksheets(lngFromSheetIndex) 49 50 ' 2. コピー元のシートを1行目から検索 51 ' 3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、[開発]の値として変数に代入しておく。 52 53 ' 4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合) 54 55 ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 56 57 ' 5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合) 58 59 ' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 60 61 ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 62 63 End If 64 65 Next lngFromSheetIndex 66 67 ' 見つかったExcelブックを閉じる 68 Call wbFrom.Close(True) 'セーブはしない 69 Set wbFrom = Nothing '参照の解除 70 71 ' 次のExcelファイルを検索 72 strFromXMLFileName = Dir() 73 Loop 74 75sample1_End: 76On Error Resume Next 77Exit Sub 78 79'----- エラー処理 80sample1_Error: 81Resume sample1_End: 82End Sub 83

投稿2020/09/27 04:51

編集2020/09/27 10:11
kuma_kuma_

総合スコア2506

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

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

icecleam

2020/09/27 05:05

ご丁寧にありがとうございます。 以前のコードと比べ、一つ一つの処理内容が綺麗に明記してあり、とても見やすくなりました。 内容も確認し、当たり前ですが実行しても何も転記はされませんが、コンパイルエラーもないことを確認しました。 あとはやはり以下の処理ですね。。 そこの書き方まで教えていただけないでしょうか。。 ---- ' 2. コピー元のシートを1行目から検索 ' 3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、[開発]の値として変数に代入しておく。 ' 4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合) ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 ' 5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合) ' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 -------
kuma_kuma_

2020/09/27 05:09

だから手順をはしよらない! 順番に書いていくんだから! 質問者様が書かれていた内容から今回の内容なにが変わりましたか?
icecleam

2020/09/27 05:20

はい、、 すみませんでした 変わった箇所は ' 書きこむ行位置2行目から というところと 担当者、工数などの値を「開発」との相対位置(i + 3など)でとってきているのではなく、「結合セル」の条件でとってきているというところでしょうか。
kuma_kuma_

2020/09/27 05:26

ここに書いた私の回答は、質問者様が書かれていた内容の清書です。 清書する際どこをどうやって清書されたか?を聞いているのです。 私がいくらここで清書しても質問者様が今後「こうやって書けばいいんだ」とわからないと話が続かないので確認しているのです。 今回答が付かなくなっている理由がそこにある事が理解できますか?
icecleam

2020/09/27 05:30

はい、それは分かっているつもりです。 申し訳ありません、「質問前のソースと清書内容の処理の違い」という意味かと思い、上記のように記載しました。 繰り返しになりますが 上記で記載していただいたソースが私の質問の内容の清書ということは理解できています。
kuma_kuma_

2020/09/27 05:32 編集

いやなにが清書されているか聞いているのです。
icecleam

2020/09/27 05:38

何が清書されているか。。。というのは以下の内容のことでしょうか。。? ごめんなさい、「何が」の意味がよくわからないです。。 ' 2. コピー元のシートを1行目から検索 ' 3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、[開発]の値として変数に代入しておく。 ' 4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合) ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 ' 5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合) ' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。
kuma_kuma_

2020/09/27 05:44

そこからですか...。 失礼ですが質問者様の欠点はそこです。 人からもらった物を「できたからいいや」で済ますからどんどんおかしな方向に進んで結果「スパゲッティソース」と揶揄される内容の「ソースコード」になって質問しても質問内容と「コード」が違うため回答を得られないのです。 以前私が書いたことを覚えていますか? ・コメントにはしっかり判るように記載を行う ・変数名は判りやすく記載する もう一度清書した内容を確認してください。
icecleam

2020/09/27 05:51

すみません、意味を履き違えていました。 以前の私のソースとkuma_kuma_さんのソースの違いは ・一つ一つの処理にコメントが明記されていて見やすくなっている ・変数に m,nのような一目でわかりづらいものが使われていない ということになると思います。
kuma_kuma_

2020/09/27 05:53

> ・変数に m,nのような一目でわかりづらいものが使われていない もっと具体的に
icecleam

2020/09/27 05:58

変数に m,nのような一目でわかりづらいものが使われていない →変数に m,nのような簡略化された一目でわかりづらいものが使われておらず、分かりやすい(一目で意味の想像がつく)変数名が使われている。
kuma_kuma_

2020/09/27 06:01

> →変数に m,nのような簡略化された一目でわかりづらいものが使われて おらず、 >分かりやすい(一目で意味の想像がつく)変数名が使われている。 じゃなぜこの変数名は一目で意味の想像がつく名称なのですか? (どういうルールで書かれていますか?)
icecleam

2020/09/27 06:09

xlsFrom を例に出すと、「〜からxlsを転記 → 転記するということは取得元」 のように英語の意味からこのソースを全く知らない人が見てもある程度は推測して見やすくなっているため でしょうか? またまた言葉が足りなかったらごめんなさい。。
kuma_kuma_

2020/09/27 06:17

そうです。今回変数名は まず 「ハンガリアン記法 - Wikipedia」(否定的な方もいらっしゃいますが) https://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%B3%E3%82%AC%E3%83%AA%E3%82%A2%E3%83%B3%E8%A8%98%E6%B3%95 にてその変数の型を判るようにする。 次に From,Toとコピーする側される側で判るように記載を変える。 その次に その変数の目的となります 例として lngFromRowsNo 検索する行位置 の場合 "lng" + "From"+ "RowsNo" に分解できます。 こうやって変数名に一定のルールを持たせて書かれたソースコードは 1日後、1年後、10年後、の質問者様が見てもすぐに思い出すでしょう また他人が見ても「一定のルールがある」とわかればソースコードの解析は容易です。 ここまでが日本語で書かれた内容をソースコードに変換する際の注意点となります。 長くなりましたので回答を新たに作成します。
icecleam

2020/09/27 06:21

ご丁寧に本当にありがとうございます 今後マクロを勉強していく上で、これ以上にないほど勉強になります。 大変お手数ですが 回答の作成のほど、よろしくお願いします。
icecleam

2020/09/27 06:43

以下のようになりました。 コメント3に関しては少しだけ変更をしています。 後のところは、昨晩考えてもわからなかった箇所になります。。 また、以下の修正内容でなぜか 「参照が無効、または不完全です」というエラーが出てしまいます。。(コメント2のUsedRange) 重ね重ねで申し訳ありませんが、ソースをどう書けば良いのか、教えていただきたいです。 '***** ここから ' 2. コピー元のシートを1行目から検索 For lngFromSheetIndex = 1 To .UsedRange.Rows.Count ' 3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、またはセルが結合されていない場合、[開発]の値として変数に代入しておく。 If (Left(.Cells(i, 2).Value, 2) = "A1" Or Left(.Cells(i, 2).Value, 2) = "B1" Or Left(.Cells(i, 2).Value, 2) = "C1") And .Cells(i, 2).MergeCells = False Then End If ' 4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合) ' 4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。 ' 5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合) ' 5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。 ' ※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動 lngRowsNo = lngRowsNo + 1 Next i '***** ここまで End If Next lngFromSheetIndex
kuma_kuma_

2020/09/27 06:46

※返信は向こうの回答に記載下さい。
icecleam

2020/09/27 06:48

失念していました。 申し訳ありません
guest

0

先の回答にも書きましたがまず日本語で自分がコピー元の情報をどうやって見ているのかを日本語で書きだします。

ますは
A. 手順のおさらいです①
コピー元の情報は上の1行目から順番に検索していきます
1行目、2行目、3行目、...
で次にそこに何か書かれているか?で処理の判断を行います。

B. 手順のおさらいです②
何か書かれているか?が判ればどこから値を取得すればよいかが判ります。

C. 手順のおさらいです③
値が取得できたらコピー先のシートに情報を書きこみます。
この際行に追加していきますので書きこむと位置が1行ずれます。

まずここまでは理解できますか?
無かったらコメントに書いてください。

つぎに上の内容をもう少し具体的に書いたのが下の手順です。

_1. コピー先の開始行は2行目から開始とする。

_2. コピー元のシートを1行目から検索
_3. B列に"A1"or"B1"or"C1"で始まる文字列がある場合、[開発]の値として変数に代入しておく。

_4. C列が4セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 4 の場合)

__4.1. C列に"担当者"という文字列が入っている場合、表のヘッダーとして[年月]の値をコピー先の行へ設定する。

_5. C列が2セル結合している場合(.MergeCellsがTrueの時に.MergeArea.Count = 2 の場合)

__5.1. C列に文字列が入っている場合、表の明細として[担当者][工数]の値をコピー先の行へ設定する。

※コピー先の行へ設定した場合追加なので、コピー先は次の行へ移動

これは理解できましたか?理解できないならその点をコメントして下さい。

投稿2020/09/27 03:57

編集2020/09/27 04:02
kuma_kuma_

総合スコア2506

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

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

icecleam

2020/09/27 04:06 編集

ご丁寧にありがとうございます >つぎに上の内容をもう少し具体的に書いたのが下の手順です。 これ以降の1〜4の実装をする際にのソースの書き方が考えても解らないという内容の質問ですので、今回は具体的なソースを教えていただきたいです。。 すみません、この書き方だとおそらく基本的な知識で書けるものなのでしょうが、昨晩考えても実装することができなかったので。。 上記記載のご回答いただいている内容は理解できているつもりです
kuma_kuma_

2020/09/27 04:08

手順をはしよらないで。 まずA. B. C. は理解できましたか?
icecleam

2020/09/27 04:09

すみません、A,B,Cは理解できています。
kuma_kuma_

2020/09/27 04:12

次に_1.、_2.、...の日本語で書かれている処理の意味は分かりますか? どうしてこのような処理なのかという事は理解できますか?
icecleam

2020/09/27 04:15

kuma_kuma_さんが記載してくださった日本語の内容は全て理解できています。 その理解した日本語をソースで実装する際に、行き詰まっているという状況です。何度もすみません。。。
kuma_kuma_

2020/09/27 04:19

すみませんは書かなくていいです。 そうしたら一度今までのソースを整理しましょう 回答で整理した分を作成しますので、いままで書いたソースはメモ帳にコピーして保存しておいて下さい。
icecleam

2020/09/27 04:22

承知致しました。 お手数をおかけします。 メモ帳に残しておきます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問