Excel VBA 質問スレッド №1570 (解決済)

consolidate を使った次のコードの誤りを教えて下さい

投稿者 : 初心者     投稿日時 : 2023/09/18(Mon) 13:13:24     OS : Windows 10     EXCEL : Excel 2019
複数の表を統合(集計)する方法の一つにconsolidateを使う方法があることを知り、下記のコードを試しました。その結果、C列以降の文字列と数値の列はうまく複数の表が統合・集計されますが、何故かB列だけタイトルだけが表示されその下の文字列(氏名)がうまく統合されず空白になってしまいます。また、A列のデータ(コード)はすべて表示されますがタイトルが表示されません。コードにどこか問題があると思うのですがよくわかりません。どなたか分かる方教えて頂けると幸いです。

With Worksheets("Sheet1")
.Cells.Clear
.Range("A1").consolidate
Sources:=Array("4月!R1C1:R400C40","5月!R1C1:R400C40","6月!R1C1:R400C40"~"12月!R1C1:R400C40"), _
Function:=xlSum,TopRow:=True,LeftColumn:=True,CreateLinks:=False
end With

スポンサーリンク
[返信 1] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : tek     投稿日時 : 2023/09/18(Mon) 19:54:10
A1セルが空白になるのはたぶん仕様です。
B列は文字列ですので統合対象外です。
統合後、VBAで、
A1セルに値を入れて下さい。
B2セル以下はVlookupなどで4月や12月シートに存在する名前を参照すれば良いでしょう

[返信 2] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : tek     投稿日時 : 2023/09/18(Mon) 20:05:33
訂正

>B列は文字列ですので統合対象外です。

B列は文字列ですので Function:=xlSum では統合対象外です。

[返信 3] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : ピロリ     投稿日時 : 2023/09/18(Mon) 20:09:24
失礼します。

<VBA consolidate 使い方> などで検索し、仕様を確認されると良いでしょう。 下記など分かり易いと思います。
http://www.eurus.dti.ne.jp/~yoneyama/Excel/vba/vba_consolidate.html
https://akira55.com/consolidate/

[返信 4] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : 初心者     投稿日時 : 2023/09/19(Tue) 06:33:23
■[返信 1] tekさん(2023-09-18 19:54:10)の記事
> A1セルが空白になるのはたぶん仕様です。
> B列は文字列ですので統合対象外です。
> 統合後、VBAで、
> A1セルに値を入れて下さい。
> B2セル以下はVlookupなどで4月や12月シートに存在する名前を参照すれば良いでしょう



返信有り難うございます。
後で気がついたのですがコードも数字として集計されてしまっていました。
もしvlookupを使うにしても難しいですね。consolidateは処理が早いので
なんとかできないかと思いましたが難しいですね。

[返信 5] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : 初心者     投稿日時 : 2023/09/19(Tue) 06:59:33
■[返信 3] ピロリさん(2023-09-18 20:09:24)の記事
> 失礼します。

> <VBA consolidate 使い方> などで検索し、仕様を確認されると良いでしょう。 下記など分かり易いと思います。
> http://www.eurus.dti.ne.jp/~yoneyama/Excel/vba/vba_consolidate.html
> https://akira55.com/consolidate/



返信有り難うございます。
こちらのサイトも当初チェックさせて頂いたんですが、文字列のことに関しては
特別説明はありませんでした。このサイトの例を使い2列目に文字列を入れてみましたが
同じように消えてしまいました。
どうやら文字列でも1列目はそのまま残るようです。
C列が日付になっておりそれが残っているのにと思いましたがよく見ると当然ですが、
日付も加算されていました。A列のコードもよく見ると加算されてしまっていました。
index match を使った時はものすごく処理時間がかかりますが、consolidateは一瞬で
処理できます。文字列のところがもったいないですね。
ピボットテーブルは得意じゃないのですが、ピボットテーブルでもタイトルや行の並び方
が表毎に違っていても複数のシートを統合できるようです。できればVBAで一瞬で処理
したかったのですが難しそうですね。

[返信 6] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : ピロリ     投稿日時 : 2023/09/19(Tue) 09:27:38
■[返信 5] 初心者さん(2023-09-19 06:59:33)の記事
> ・・・2列目に文字列を入れてみましたが、同じように消えてしまいました。
> どうやら文字列でも1列目はそのまま残るようです。
> C列が日付になっておりそれが残っているのにと思いましたがよく見ると当然ですが、
> 日付も加算されていました。
Function:=xlSum, TopRow:=True, LeftColumn:=True を指定しているため、1行目と 1列目がタイトル(串刺しする検索キーワード)、
2行目以降・2列目以降が合計(串刺し計算)の範囲なので、当然の結果ですね。

> A列のコードもよく見ると加算されてしまっていました。
A列のコードって、上で仰っていた「1列目はそのまま残る」なのでは? 検索キーワードなので加算されるはずはないと思いますが。
私の環境では 1行目と 1列目は加算されていません。(加算は 2行目以降・2列目以降) ちなみに下のコードで動作確認してます。
仰っていることに矛盾を感じるのですが、もう少し動作確認(検証)してみてはいかがでしょうか?

Sub Test()
    With Worksheets("Sheet1")
        .Cells.ClearContents
        .Range("A1").Consolidate _
            Sources:=Array("4月!R1C1:R400C40", "5月!R1C1:R400C40", "6月!R1C1:R400C40"), _
            Function:=xlSum, TopRow:=True, LeftColumn:=True, CreateLinks:=False
    End With
End Sub

[返信 7] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : 初心者     投稿日時 : 2023/09/19(Tue) 18:26:03
■[返信 6] ピロリさん(2023-09-19 09:27:38)の記事
> ■[返信 5] 初心者さん(2023-09-19 06:59:33)の記事

> A列のコードって、上で仰っていた「1列目はそのまま残る」なのでは? 検索キーワードなので加算されるはずはないと思いますが。
> 私の環境では 1行目と 1列目は加算されていません。(加算は 2行目以降・2列目以降) ちなみに下のコードで動作確認してます。
> 仰っていることに矛盾を感じるのですが、もう少し動作確認(検証)してみてはいかがでしょうか?

返信が遅くなり失礼しました。A列が変わらないのは確かにおっしゃる通りでした。並べ替えが行われて見た目が違ったため勘違いしてました。
それにしても2列目以降の文字列が消えてしまうのではconsolidateは使えないですね。処理が早いだけに残念です。
お手数をおかけしました。仕方がないので、この質問は解決済みとさせて頂きます。

忙しいなか、ご対応いただき有り難うございました。

[返信 8] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : ピロリ     投稿日時 : 2023/09/19(Tue) 20:28:51
■[返信 7] 初心者さん(2023-09-19 18:26:03)の記事
> それにしても2列目以降の文字列が消えてしまうのではconsolidateは使えないですね。処理が早いだけに残念です。
もう解決済になってしまって、ご覧いただけないかも知れませんが、A列のコードというのは氏名コード(人によって異なるユニークなデータ)のことですよね。
氏名コードは重要なので書換わってしまってたらアウトでしたが、書換わっていないということでしたら利用できるのでは?
要は、現状のまま consolidateを処理させて、その後にデータ補正させることが出来るのでは? 補正するデータ量にもよるでしょうけど・・・

今ネックとなっているのは下記の認識です。
①A1セルにタイトルが出ない(TopRow:=True, LeftColumn:=Trueの弊害)ので、「コード」の文字を設定したい。
②B2から下の氏名が出ない(Function:=xlSumの弊害)ので、氏名コードに対応する氏名を設定したい。
③C2から下の日付が加算されてしまう(Function:=xlSumの弊害)ので、加算の必要のない日付は「-」などに書換える?

下のようなデータ補正では駄目ですかね。(即興なので上手く動くかは分かりませんが。) 的外れでしたらすいませんけど・・・

Sub Sample()
    Dim i As Long, j As Long
    Dim FoundCell As Variant
    
    With Worksheets("Sheet1")
        .Cells.ClearContents
        .Range("A1").Consolidate _
            Sources:=Array("4月!R1C1:R400C40", "5月!R1C1:R400C40", "6月!R1C1:R400C40", _
                           "7月!R1C1:R400C40", "8月!R1C1:R400C40", "9月!R1C1:R400C40", _
                           "10月!R1C1:R400C40", "11月!R1C1:R400C40", "12月!R1C1:R400C40"), _
            Function:=xlSum, TopRow:=True, LeftColumn:=True, CreateLinks:=False
        
        .Range("A1") = "コード"     '①A1セルへタイトル:「コード」を設定
        For i = 2 To .Cells(Rows.Count, "A").End(xlUp).Row      '氏名コードのループ
            .Range("C" & i) = "-"  '③C列の日付欄は「-」とする
            For j = 4 To 12                                     '4月~12月のループ
                Set FoundCell = Worksheets(j & "月").Range("A:A").Find(.Range("A" & i))
                If Not FoundCell Is Nothing Then                '氏名コードが検索できたら、
                    .Range("B" & i) = FoundCell.Offset(0, 1)    '②B列に対応する氏名を設定
                    Exit For                                    'ループ終了
                End If
            Next j
        Next i
    End With
End Sub

[返信 9] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : 初心者     投稿日時 : 2023/09/20(Wed) 06:43:09
■[返信 8] ピロリさん(2023-09-19 20:28:51)の記事
> ■[返信 7] 初心者さん(2023-09-19 18:26:03)の記事
> > それにしても2列目以降の文字列が消えてしまうのではconsolidateは使えないですね。処理が早いだけに残念です。
> もう解決済になってしまって、ご覧いただけないかも知れませんが、A列のコードというのは氏名コード(人によって異なるユニークなデータ)のことですよね。
> 氏名コードは重要なので書換わってしまってたらアウトでしたが、書換わっていないということでしたら利用できるのでは?
> 要は、現状のまま consolidateを処理させて、その後にデータ補正させることが出来るのでは? 補正するデータ量にもよるでしょうけど・・・

> 今ネックとなっているのは下記の認識です。
> ①A1セルにタイトルが出ない(TopRow:=True, LeftColumn:=Trueの弊害)ので、「コード」の文字を設定したい。
> ②B2から下の氏名が出ない(Function:=xlSumの弊害)ので、氏名コードに対応する氏名を設定したい。
> ③C2から下の日付が加算されてしまう(Function:=xlSumの弊害)ので、加算の必要のない日付は「-」などに書換える?

> 下のようなデータ補正では駄目ですかね。(即興なので上手く動くかは分かりませんが。) 的外れでしたらすいませんけど・・・

> Sub Sample()
> Dim i As Long, j As Long
> Dim FoundCell As Variant

> With Worksheets("Sheet1")
> .Cells.ClearContents
> .Range("A1").Consolidate _
> Sources:=Array("4月!R1C1:R400C40", "5月!R1C1:R400C40", "6月!R1C1:R400C40", _
> "7月!R1C1:R400C40", "8月!R1C1:R400C40", "9月!R1C1:R400C40", _
> "10月!R1C1:R400C40", "11月!R1C1:R400C40", "12月!R1C1:R400C40"), _
> Function:=xlSum, TopRow:=True, LeftColumn:=True, CreateLinks:=False

> .Range("A1") = "コード" '①A1セルへタイトル:「コード」を設定
> For i = 2 To .Cells(Rows.Count, "A").End(xlUp).Row '氏名コードのループ
> .Range("C" & i) = "-" '③C列の日付欄は「-」とする
> For j = 4 To 12 '4月~12月のループ
> Set FoundCell = Worksheets(j & "月").Range("A:A").Find(.Range("A" & i))
> If Not FoundCell Is Nothing Then '氏名コードが検索できたら、
> .Range("B" & i) = FoundCell.Offset(0, 1) '②B列に対応する氏名を設定
> Exit For 'ループ終了
> End If
> Next j
> Next i
> End With
> End Sub

こんなコードが即興で書けるなんてすごいですね。
私も考えたのですが、名前と社員コードを別シートにしておいてから名前をA列にしてconsolidateで
統合し、その後で名前とリンクさせて一つの表にするという順番でやれば良いのではと思いました。
上のコードのレベルとは前々違いますが。これから勉強させて頂きます。
お忙しい中、ご親切に有り難うございました。感謝いたします。

[返信 10] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : ピロリ     投稿日時 : 2023/09/20(Wed) 08:31:38
■[返信 9] 初心者さん(2023-09-20 06:43:09)の記事
> 私も考えたのですが、名前と社員コードを別シートにしておいてから名前をA列にしてconsolidateで
> 統合し、その後で名前とリンクさせて一つの表にするという順番でやれば良いのではと思いました。
名前を A列にして検索キーワードにするってことでしょうか? 検索キーワードは氏名コードにしないと同姓同名が対応できないと思いますよ。
同姓同名の2名分が統合(合計算出)されてしまうのでは。 良く検討と検証して下さいね。
余談ですが、氏名コード表を作成するなら、9月だけスポットで入っていた人も考慮すると、4月~12月シートをORしないといけないですよね。
ちなみに、1月~3月は? 一応、気になりましたので・・・

[返信 11] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : 初心者     投稿日時 : 2023/09/20(Wed) 14:21:25
■[返信 10] ピロリさん(2023-09-20 08:31:38)の記事
> ■[返信 9] 初心者さん(2023-09-20 06:43:09)の記事
> > 私も考えたのですが、名前と社員コードを別シートにしておいてから名前をA列にしてconsolidateで
> > 統合し、その後で名前とリンクさせて一つの表にするという順番でやれば良いのではと思いました。
> 名前を A列にして検索キーワードにするってことでしょうか? 検索キーワードは氏名コードにしないと同姓同名が対応できないと思いますよ。
> 同姓同名の2名分が統合(合計算出)されてしまうのでは。 良く検討と検証して下さいね。
> 余談ですが、氏名コード表を作成するなら、9月だけスポットで入っていた人も考慮すると、4月~12月シートをORしないといけないですよね。
> ちなみに、1月~3月は? 一応、気になりましたので・・・

確かにおっしゃる通りですね。
それでは別途社員一覧のコード表はありますので、A列を社員コードのまま実行し、消えたB列の社員名をその社員一覧表と
リンクさせた方がよいですね。ただ、日付が使えないと後の分析に支障が出てしまいます。難しいですね。

[返信 12] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : 初心者     投稿日時 : 2023/09/20(Wed) 19:21:25
■[返信 10] ピロリさん(2023-09-20 08:31:38)の記事
> ■[返信 9] 初心者さん(2023-09-20 06:43:09)の記事

> 余談ですが、氏名コード表を作成するなら、9月だけスポットで入っていた人も考慮すると、4月~12月シートをORしないといけないですよね。
> ちなみに、1月~3月は? 一応、気になりましたので・・・


失礼しました。1~3月のシートもあります。

作って頂いたコードを試させて頂いたんですが、名前が途中まで表示されてからインデックスが有効範囲にありませんというメッセージがでます。
デバッグするとset foundcell=worksheets(j & "月").range("A:A").find(.range("A"& i)のところが黄色くなります。
残念なことに私の能力ではこのコードの意味が分からないので修正できません。もっと勉強しないと駄目みたいです。頑張ります。
長時間本当に有り難うございました。

[返信 13] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : 初心者     投稿日時 : 2023/09/20(Wed) 19:46:39
■[返信 12] 初心者さん(2023-09-20 19:21:25)の記事
> ■[返信 10] ピロリさん(2023-09-20 08:31:38)の記事
> > ■[返信 9] 初心者さん(2023-09-20 06:43:09)の記事

> > 余談ですが、氏名コード表を作成するなら、9月だけスポットで入っていた人も考慮すると、4月~12月シートをORしないといけないですよね。
> > ちなみに、1月~3月は? 一応、気になりましたので・・・
> >

> 失礼しました。1~3月のシートもあります。

> 作って頂いたコードを試させて頂いたんですが、名前が途中まで表示されてからインデックスが有効範囲にありませんというメッセージがでます。
> デバッグするとset foundcell=worksheets(j & "月").range("A:A").find(.range("A"& i)のところが黄色くなります。
> 残念なことに私の能力ではこのコードの意味が分からないので修正できません。もっと勉強しないと駄目みたいです。頑張ります。
> 長時間本当に有り難うございました。

実は夏賞与、冬賞与というシートもあります。
一つだけお願いです。途中までだとしても名前を表示できた仕組みを教えて頂けますでしょうか。

[返信 14] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : ピロリ     投稿日時 : 2023/09/20(Wed) 21:21:46
■[返信 13] 初心者さん(2023-09-20 19:46:39)の記事
> 実は夏賞与、冬賞与というシートもあります。
> 一つだけお願いです。途中までだとしても名前を表示できた仕組みを教えて頂けますでしょうか。

すいません。見逃していました。

 Set FoundCell = Worksheets(j & "月").Range("A:A").Find(.Range("A" & i))

まず、Worksheets(j & "月")ですが、jが 4~12のループなので、シート名「4月」~「12月」が対象になります。
   Range("A:A")は、そのシートの A列全体です。
   .Range("A" & i)は、シート名「Sheet1」の i行目の氏名コードになります。
i=10,j=5の場合、シート名「5月」の A列全体から、シート名「Sheet1」の10行目の氏名コードで Find(検索)します。
検索結果、見付かったセルが FoundCellへセットされます。(見付からなかったら FoundCell Is Nothing です)
見付かったら FoundCell.Offset(0, 1) つまり見付かったセルの一つ右側のセルの値を氏名としています。
氏名が取得できたら、それ以上検索する必要は無いので、Exit Forで jループは抜けています。
見付からなかったら、次のシート名「6月」での検索に移ります。
大部分の氏名コードは、シート名「4月」の時点で検索できていると思いますが、9月スポット人員も有り得ますので・・・

検索なので「101」で検索した場合、「1012」も「12101」も検索されてしまいます。
つまり、氏名コードの桁数は固定(6文字とか)であることが前提になります。

私は氏名コード 6文字固定で動作確認しましたが、特にエラーは出ていません。
検索できた氏名コードとエラーになった氏名コードに、何か違いがあるのでしょうかね・・・
また、氏名コードの検索は、賞与だけを貰う人はいないので、月のシートの検索のみで良いのではないでしょうか。

それから、不明点は <vba ○○○> と、頭に vbaを付けて検索すると良いですよ。

[返信 15] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : ピロリ     投稿日時 : 2023/09/20(Wed) 21:50:32
ちなみに「インデックスが有効範囲にありません」の件ですが、シート「4月」~「12月」(数字部は半角です)は
全て存在していますよね? 存在しないシートを参照した場合はエラーになりそうなので念のための確認です。

[返信 16] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : 初心者     投稿日時 : 2023/09/20(Wed) 23:21:56
■[返信 15] ピロリさん(2023-09-20 21:50:32)の記事
> ちなみに「インデックスが有効範囲にありません」の件ですが、シート「4月」~「12月」(数字部は半角です)は
> 全て存在していますよね? 存在しないシートを参照した場合はエラーになりそうなので念のための確認です。



本当に有り難うございます。
95%位理解できた気がします。
社員コードは2100-0201-9849のように4桁の数字が3つ繋がったものです。通常は下4桁を使いますが給与ソフトのコードはこうなっています。
シートはすべて埋まっています。このコードが原因なのかもしれませんね。
いずれにしても本当に有り難うございました。後は自分でいろいろ試してみます。おかげさまで少し知識が深まりました。
有り難うございました。

[返信 17] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : ピロリ     投稿日時 : 2023/09/21(Thu) 00:09:36
■[返信 16] 初心者さん(2023-09-20 23:21:56)の記事
> シートはすべて埋まっています。
そうですかぁ~。
例えば、氏名が表示できた氏名コードは 4月に有って表示ができた。エラーになった氏名コードは 4月に無かったので
5月や 6月を検索しようとしたが、シート名が「6月」(数字部が全角)だったので、シートが参照できずにエラーみたいな
感じかなぁ~と思っていたのですが・・・
ステップ実行して、まずはどのシートを参照しようとしてエラーになったか特定した方が良いかも知れませんね。

[返信 18] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : 初心者     投稿日時 : 2023/09/21(Thu) 05:56:38
■[返信 17] ピロリさん(2023-09-21 00:09:36)の記事
> ■[返信 16] 初心者さん(2023-09-20 23:21:56)の記事

> 例えば、氏名が表示できた氏名コードは 4月に有って表示ができた。エラーになった氏名コードは 4月に無かったので
> 5月や 6月を検索しようとしたが、シート名が「6月」(数字部が全角)だったので、シートが参照できずにエラーみたいな
> 感じかなぁ~と思っていたのですが・・・
> ステップ実行して、まずはどのシートを参照しようとしてエラーになったか特定した方が良いかも知れませんね。



手のかかる初心者にお付き合い頂いて本当にすみません。授業料をお支払いしないといけない気持ちで本当に恐縮しています。

アドバイスのとおり調べたところ10月のシートが全角になっていました。それを修正して実行してみましたがやはり同じエラー
になりました。

集計シートの38行目までは名前が表示されるのですが、39行目のコードを4月のシートから順に検索していくと7月以降のシート
にありました。40行目のコードは4月以降のシートにありました。

理解度は97%になりました。iとjを使ってシートと行を次々に移動させて元のシートから名前を拾っていくんですね。
こういう発想ができる人はすごいですね。頭の構造が違います。findメソッドも知りませんでした。VBAはおもしろいですね。

[返信 19] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : ピロリ     投稿日時 : 2023/09/21(Thu) 09:31:25
そこまで解読できたのなら、理解度100%で良いのでは・・・

Set FoundCell = Worksheets(j & "月").Range("A:A").Find(.Range("A" & i))
で「インデックスが有効範囲にありません」のエラーですよね。
Findメソッドのパラメータは文字列なので、.Range("A" & i)の値でのエラーは考え辛いし。
Range("A:A")は必ず存在するし。となれば、Worksheets(j & "月") が問題としか思えないのですが・・・
「10月」シート以外にも怪しいシート名とか有りませんか?
試しに下のエラートラップを実行してみて下さい。1月~12月で存在しないシート名を表示させてます。

それでもシート名に問題が無いようなら、ステップ実行してシラミ潰しって感じでしょうかね。

Sub エラートラップ()
    Dim j As Long, msg As String
    On Error GoTo ERROR_LABEL           'エラー宣言(エラー発生時にエラー処理をさせる)
    msg = ""
    For j = 1 To 12                     '1月~12月分のループ
        Worksheets(j & "月").Select     'その月のシートを選択させてみる
    Next j
    If msg = "" Then
        MsgBox "シート名に問題なし"     '正常メッセージを表示
    Else
        MsgBox msg                      'エラーメッセージを表示
    End If
        
    Exit Sub                            '処理終了
    
ERROR_LABEL:    'エラー処理
    msg = msg & "「" & j & "月」シートが無い" & vbCrLf  'エラーメッセージを作成する
    Resume Next                                         'エラー発生時の次のStepへ戻る
End Sub

[返信 20] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : 初心者     投稿日時 : 2023/09/21(Thu) 23:23:42
■[返信 19] ピロリさん(2023-09-21 09:31:25)の記事
> そこまで解読できたのなら、理解度100%で良いのでは・・・

> Set FoundCell = Worksheets(j & "月").Range("A:A").Find(.Range("A" & i))
> で「インデックスが有効範囲にありません」のエラーですよね。
> Findメソッドのパラメータは文字列なので、.Range("A" & i)の値でのエラーは考え辛いし。
> Range("A:A")は必ず存在するし。となれば、Worksheets(j & "月") が問題としか思えないのですが・・・
> 「10月」シート以外にも怪しいシート名とか有りませんか?
> 試しに下のエラートラップを実行してみて下さい。1月~12月で存在しないシート名を表示させてます。

> それでもシート名に問題が無いようなら、ステップ実行してシラミ潰しって感じでしょうかね。

> Sub エラートラップ()
> Dim j As Long, msg As String
> On Error GoTo ERROR_LABEL 'エラー宣言(エラー発生時にエラー処理をさせる)
> msg = ""
> For j = 1 To 12 '1月~12月分のループ
> Worksheets(j & "月").Select 'その月のシートを選択させてみる
> Next j
> If msg = "" Then
> MsgBox "シート名に問題なし" '正常メッセージを表示
> Else
> MsgBox msg 'エラーメッセージを表示
> End If

> Exit Sub '処理終了

> ERROR_LABEL: 'エラー処理
> msg = msg & "「" & j & "月」シートが無い" & vbCrLf 'エラーメッセージを作成する
> Resume Next 'エラー発生時の次のStepへ戻る
> End Sub

本当にすみません。
上記のコードが私にはまだよく理解できませんが、試しにやってみたところ、1月のシートが選択されworksheet(j&"月").selectのところが黄色くなります。
シートの並びは4月から12月まで並んだあと1~3月が続きます。因みに1月は半角になっています。

ステップ実行をしたところ38行目までは4月のシートにあるので順調に動きましたが、ローカルウインドウで見ると39行目でfoundcellがnothingになり変数jが
5に変わり5月のA列を検索しますが、そこでエラーになりインデックスが有効範囲に無いというメッセージがでます。このコードは7月のシートにあります。
初心者ながら考えたのですが、If Not FoundCell Is Nothing Then というコードの次に、もしFoundCellがNothingだったらjに1を足して検索を続けなさいと
いうような命令を入れてはどうかと考えましたが間違っているでしょうか。ただ残念ながらどうやって書けばよいのかまだ力がありません。

また、for next でiが順番にに変わっていくのに Nothingになるまでfor nextのjが変わらないようにするというコードの書き方の順番というか仕組みも
今一つ理解できていません。

またご親切にすがってしまいます。すみません。

[返信 21] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : 初心者     投稿日時 : 2023/09/22(Fri) 06:10:14
■[返信 20] 初心者さん(2023-09-21 23:23:42)の記事
> ■[返信 19] ピロリさん(2023-09-21 09:31:25)の記事
> > そこまで解読できたのなら、理解度100%で良いのでは・・・
> >
> > Set FoundCell = Worksheets(j & "月").Range("A:A").Find(.Range("A" & i))
> > で「インデックスが有効範囲にありません」のエラーですよね。
> > Findメソッドのパラメータは文字列なので、.Range("A" & i)の値でのエラーは考え辛いし。
> > Range("A:A")は必ず存在するし。となれば、Worksheets(j & "月") が問題としか思えないのですが・・・
> > 「10月」シート以外にも怪しいシート名とか有りませんか?
> > 試しに下のエラートラップを実行してみて下さい。1月~12月で存在しないシート名を表示させてます。
> >
> > それでもシート名に問題が無いようなら、ステップ実行してシラミ潰しって感じでしょうかね。
> >
> > Sub エラートラップ()
> > Dim j As Long, msg As String
> > On Error GoTo ERROR_LABEL 'エラー宣言(エラー発生時にエラー処理をさせる)
> > msg = ""
> > For j = 1 To 12 '1月~12月分のループ
> > Worksheets(j & "月").Select 'その月のシートを選択させてみる
> > Next j
> > If msg = "" Then
> > MsgBox "シート名に問題なし" '正常メッセージを表示
> > Else
> > MsgBox msg 'エラーメッセージを表示
> > End If
> >
> > Exit Sub '処理終了
> >
> > ERROR_LABEL: 'エラー処理
> > msg = msg & "「" & j & "月」シートが無い" & vbCrLf 'エラーメッセージを作成する
> > Resume Next 'エラー発生時の次のStepへ戻る
> > End Sub

> 本当にすみません。
> 上記のコードが私にはまだよく理解できませんが、試しにやってみたところ、1月のシートが選択されworksheet(j&"月").selectのところが黄色くなります。
> シートの並びは4月から12月まで並んだあと1~3月が続きます。因みに1月は半角になっています。

> ステップ実行をしたところ38行目までは4月のシートにあるので順調に動きましたが、ローカルウインドウで見ると39行目でfoundcellがnothingになり変数jが
> 5に変わり5月のA列を検索しますが、そこでエラーになりインデックスが有効範囲に無いというメッセージがでます。このコードは7月のシートにあります。
> 初心者ながら考えたのですが、If Not FoundCell Is Nothing Then というコードの次に、もしFoundCellがNothingだったらjに1を足して検索を続けなさいと
> いうような命令を入れてはどうかと考えましたが間違っているでしょうか。ただ残念ながらどうやって書けばよいのかまだ力がありません。

> また、for next でiが順番にに変わっていくのに Nothingになるまでfor nextのjが変わらないようにするというコードの書き方の順番というか仕組みも
> 今一つ理解できていません。

> またご親切にすがってしまいます。すみません。

追伸
コードが見つからずJ+1で次のシートに移って検索を続けた場合、次のコードの検索が該当シートから始まってしまい問題が出ますね。また4月のシートに戻って
やり直すようなコードが必要かと思いますがどう書いたら良いか複雑すぎて手が出ません。

[返信 22] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : tek     投稿日時 : 2023/09/22(Fri) 07:34:38
話が変な方向に行っていると思います。

■[返信 1] tekさん(2023-09-18 19:54:10)の記事

> B2セル以下はVlookupなどで4月や12月シートに存在する名前を参照すれば良いでしょう

シート名は、
https://learn.microsoft.com/ja-jp/office/vba/api/excel.worksheet.name
https://learn.microsoft.com/ja-jp/office/vba/api/excel.range.address
などに任せておけば良いでしょう

方法は色々ありますが、今回はVlookupが適していると思います。

Sub 統合後の名前埋め()
    Dim sh As Worksheet
    Dim i As Long
    Dim 名前 As Range
    Dim 検索範囲 As String
    
    Set sh = Worksheets("Sheet1")   '統合シート
    Set 名前 = sh.Range("A2", sh.Cells(sh.Rows.Count, 1).End(xlUp)).Offset(, 1) 'B列範囲
    For i = 1 To Worksheets.Count   '全てのシートを繰り返す
        If WorksheetFunction.CountBlank(名前) = 0 Then Exit For     '名前が埋まれば終了
        If Worksheets(i).Name <> sh.Name Then       '自身のシートは除く
            検索範囲 = Worksheets(i).Range("A1").CurrentRegion.Address(True, True, xlR1C1, True)
            With 名前.SpecialCells(xlCellTypeBlanks)    '空白セルに数式を埋める
                .Formula2R1C1 = "=iferror(VLOOKUP(RC[-1]," & 検索範囲 & ",2,FALSE),"""")"
                .Value = .Value     '値に変換
            End With
        End If
     Next
End Sub

[返信 23] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : ピロリ     投稿日時 : 2023/09/22(Fri) 07:56:59
■[返信 20] 初心者さん(2023-09-21 23:23:42)の記事
> 上記のコードが私にはまだよく理解できませんが、試しにやってみたところ、1月のシートが選択されworksheet(j&"月").selectのところが黄色くなります。
> シートの並びは4月から12月まで並んだあと1~3月が続きます。因みに1月は半角になっています。
Sub エラートラップ() の方はステップ実行しなくても良いです。
そのまま実行してくれれば存在しないシートの一覧をメッセージ表示してくれるように作っていますので。
その一覧に「1月」や「5月」が表示されるのではないでしょうか。 もう一度普通に走らせてみて下さい。
さて、「1月」シートが Select 出来なかった(エラー)の件ですが、本当に「1月」というシート名でしょうか?
スペースなど別の文字が混入されているとか、「1」のつもりで半角の「L」とか、文字列が「1月」(完全一致)でないと Select 出来ませんので。

> 初心者ながら考えたのですが、If Not FoundCell Is Nothing Then というコードの次に、もしFoundCellがNothingだったらjに1を足して検索を続けなさいと
> いうような命令を入れてはどうかと考えましたが間違っているでしょうか。ただ残念ながらどうやって書けばよいのかまだ力がありません。
現状そういう処理になっていますよ。
FoundCell Is Nothing だったら Then ~ EndIf は処理しないため Next j へ行くので、次の月(j+1)の検索処理へ移行しています。
If Not FoundCell Is Nothing は「 FoundCell Is Nothing でなかったら、」つまり「 FoundCell に検索できたセルが入ったら、」ということです。
つまり、そのシートに氏名コードが有ったか無かったを判定しているだけなので、下のようなことはやっていませんし、考えなくて良いと思います。
有ったら氏名を拾って Exit For して次(i+1)の氏名コード検索、無かったら Next j して次の月(j+1)のシートで氏名コード検索すれば良いだけ。

> また、for next でiが順番に変わっていくのに Nothingになるまでfor nextのjが変わらないようにするというコードの書き方の順番というか仕組みも
> 今一つ理解できていません。

私のFindメソッドも一案ですので、tek先生のご指摘なども参考にしてご検討されると良いと思います。

[返信 24] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : ピロリ     投稿日時 : 2023/09/22(Fri) 08:53:58
もし Findメソッドを使用するなら・・・ (★のところを変えてます。)

Sub Sample2()
    Dim i As Long, j As Long
    Dim FoundCell As Variant
    
    With Worksheets("Sheet1")
        .Cells.ClearContents
        .Range("A1").Consolidate _
            Sources:=Array("4月!R1C1:R400C40", "5月!R1C1:R400C40", "6月!R1C1:R400C40", _
                           "7月!R1C1:R400C40", "8月!R1C1:R400C40", "9月!R1C1:R400C40", _
                           "10月!R1C1:R400C40", "11月!R1C1:R400C40", "12月!R1C1:R400C40"), _
            Function:=xlSum, TopRow:=True, LeftColumn:=True, CreateLinks:=False
        
        .Range("A1") = "コード"     '①A1セルへタイトル:「コード」を設定
        For i = 2 To .Cells(Rows.Count, "A").End(xlUp).Row      '氏名コードのループ
            .Range("C" & i) = "-"  '③C列の日付欄は「-」とする
            For j = 1 To Worksheets.Count                       '★全シートのループ
                If 0 < InStr(Worksheets(j).Name, "月") Then     '★シート名に「月」があれば、
                    Set FoundCell = Worksheets(j).Range("A:A").Find(.Range("A" & i))
                    If Not FoundCell Is Nothing Then             '氏名コードが検索できたら、
                        .Range("B" & i) = FoundCell.Offset(0, 1) '②B列に対応する氏名を設定
                        Exit For                                 'ループ終了
                    End If
                End If
            Next j
        Next i
    End With
End Sub

[返信 25] Re : consolidate を使った次のコードの誤りを教えて下さい
投稿者 : 初心者     投稿日時 : 2023/09/22(Fri) 12:37:43
■[返信 24] ピロリさん(2023-09-22 08:53:58)の記事
> もし Findメソッドを使用するなら・・・ (★のところを変えてます。)

> Sub Sample2()
> Dim i As Long, j As Long
> Dim FoundCell As Variant

> With Worksheets("Sheet1")
> .Cells.ClearContents
> .Range("A1").Consolidate _
> Sources:=Array("4月!R1C1:R400C40", "5月!R1C1:R400C40", "6月!R1C1:R400C40", _
> "7月!R1C1:R400C40", "8月!R1C1:R400C40", "9月!R1C1:R400C40", _
> "10月!R1C1:R400C40", "11月!R1C1:R400C40", "12月!R1C1:R400C40"), _
> Function:=xlSum, TopRow:=True, LeftColumn:=True, CreateLinks:=False

> .Range("A1") = "コード" '①A1セルへタイトル:「コード」を設定
> For i = 2 To .Cells(Rows.Count, "A").End(xlUp).Row '氏名コードのループ
> .Range("C" & i) = "-" '③C列の日付欄は「-」とする
> For j = 1 To Worksheets.Count '★全シートのループ
> If 0 < InStr(Worksheets(j).Name, "月") Then '★シート名に「月」があれば、
> Set FoundCell = Worksheets(j).Range("A:A").Find(.Range("A" & i))
> If Not FoundCell Is Nothing Then '氏名コードが検索できたら、
> .Range("B" & i) = FoundCell.Offset(0, 1) '②B列に対応する氏名を設定
> Exit For 'ループ終了
> End If
> End If
> Next j
> Next i
> End With
> End Sub

このコードを試させていただいたところ問題なく統合と表示ができました。
長いことご指導頂きありがとうございました。作って頂いたコードをじっくり
勉強させて私もかけるようになりたいと思います。
本当にありがとうございました。



当掲示板について
  • Excel VBA に関する掲示板です。Excel VBA に関する質問や疑問、それに対する解決方法など気軽に投稿してください。
  • 記事内ではHTMLのタグは使用できません。
  • 記事は一度投稿すると修正できません。内容を訂正したい場合は返信で対応してください。
  • Sub〜End Sub、Function〜End Function は自動的にプログラムコードとみなし、枠で囲って見やすくします。
  • Excel VBA とは関係ないことや、他人が不快に思うようなことなど、管理人が適当でないと判断した記事は削除する場合があります。
スポンサーリンク
返信入力フォーム
お 名 前  :
内  容   :

ステータス  :

認証コード  : キャプチャ画像 




( 処理日時 : 2023-10-01 23:24:26 )
タイトルとURLをコピーしました