[[20120904212547]] 『2件目以降の該当データを1件目の右に転記したい』(yui) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『2件目以降の該当データを1件目の右に転記したい』(yui)

こんにちは。
現在、会社でVBAを使用しての業務に初めて取り組み本を読みながら格闘しているところです。
ネットや本でも調べたのですが、同じような例がなかったためこちらで皆さんの力をお借りしたいと思い投稿させていただきました。
Excel2003、Windows XPを使用しています。

作りたいものは、下記のようなものです。

@管理番号シート

  A |B | C    | D |E 〜
1   |  |EE-33 |   |
2   |  |CC-22 |   |
3   |  |AA-11 |   |
4   |  |GG-44 |   |
5   |  |WW-55 |   |
6   |  |RR-66 |   |

A検収リストシート

  A    |B     | C    | D    |E 〜    |Oまで
1 CC-22|2/1   |1000  |物件1 |CC-22-01|
2 CC-22|3/1   |10000 |物件2 |CC-22-02|
3 EE-33|10/12 |20000 |物件A |EE-33-01|
4 LL-10|2/4   |350   |物件B |LL-10-01  
5 KK-66|3/10  |4000  |案件1 |KK-66-01   
6 GG-44|8/10  |5000  |案件2 |GG-44-01   
7 GG-44|8/12  |100000|案件3 |GG-44-02
8 GG-44|8/14  |200000|案件4 |GG-44-03   
9 FD-22|2/3   |50000 |案件5 |FD-22-01
8 FD-22|2/4   |23000 |物件C |FD-22-02
8 FD-22|2/5   |4000  |物件D |FD-22-03

@のシートのC列に管理番号を記載します。
Aの検収リストシートは毎月CVS形式で出力していきます。
データ内容は不要な列データのものも多数含んでいますので、VBAでCVSファイルを読み込んで必要な列データのみを抽出するコードを記載して検収リストシートを作成しています。

そこで、@のシートに記載した管理番号のデータを検収リストシートから取り出し、3つ目のデーターシートに下記のように転記したいのです。が、仕様に少々課題があります。

Bデーターシート

 A    |B     | C   | D |E       |〜O   |P  |Q     |R  | S      |〜AD |AE |AF〜 
1EE-33|10/12 |20000|件A|EE-33-01|      |   |      |   |        |     |     |    
2CC-22|2/1   |1000 |件1|CC-22-01|CC-22 |3/1|10000 |件2|CC-22-02|     |      
3AA-11|
4GG-44|8/10  |5000 |件2|GG-44-01|GG-44 |8/12|100000|件3|       |GG-44|8/14  |200000|件4 |GG-44-03|      |      |
5 WW-55|      |      |      |      |   
6 RR-66|   |    |    |      |   

やりたいこと
@の管理番号シートのC列とAの検収リストシートのA列を一致させて、Bのデータシートへ転記したい。
ただし、AのシートのA列管理番号は重複しているものがあり、1件〜複数件ある場合がありますが、最大4件くらいまでです。また、列項目の中には空白やゼロなどもあります。
1件目の該当データをBのシートのA列からO列へ15列転記しますが、2件目以降に該当する同じ管理番号のデータがあれば、それをシートの下方へではなく、右列P以降へどんどん横へ追加していく形で転記したいのです。
また、該当データがなかった管理番号はそのままB列以降は空欄の状態で、A列に管理番号のみ転記したいです。
検索するキー列はAのシートのA列でA列は重複した番号ですが、E列に管理番号の枝番号がついているものがあり、その番号はユニークな番号です。

検収リストシートは日々検収があがったらデータを蓄積していくものですので、一旦データが出来たらそのデータがなくなることはないですが、現時点で記載のなかった列項目に来月入力されていることがあるので、Bに転記済みのC列管理番号のものもも毎回再検索したいです。

また、データシートの管理番号は今月1件であっても来月2件に増えていることがありますので、やはり管理番号シートのC列に記載の番号は毎回再検索したいです。
ただし、2件が1件に減るなど逆はありません。

私のほうで、findnextを使って検索するコードを記載してみたのですが、
1.2件目に該当したデータを1件目の右に追加していく方法がわからない。
2.データがなかった場合に@のシートのC列の並びを崩さずに、B列意向を空白にしていく方法がわからない。

などの壁に当たってしまいました。
上記の要件を充たすにはどのようにコードを作成したらいいか助けて頂けませんか?

ちなみに考えていますのは、最初にC列に番号を記載した状態で@のシートにマクロボタンを登録して検索したい時にボタンを押すとCVSを読み込んでAのシートに検収データをよみこみ、さらに検索をかけて転記していくというものです。
検収データの読み込みまでは出来たのですが、findnextを本を読みながらコード作成をしても、検索したデータを下方に転記してしまうし、さらに該当しなかった場合に空白にしておくことができません。

空白にしたいのは、該当しなかった場合はまだ検収があがっていないものなのですが、あがる前でも他の列項目に先に入力しておきたい項目があるので、空白にして、検収があがったらそこにデータが追記できるような仕様にしたいのです。

こんなことはVBAで出来るのでしょうか?出来るとしたらどのようなコードでしょうか?

長々記載しましたが、どなたか助けていただけませんでしょうか。
宜しくお願い致します。


細かい点の修正はご自分でお願いします。

Sub test()

For i = 1 To 20
m = 0

    For n = 1 To 20
        If Sheets("管理番号シート").Cells(i, 3) = Sheets("検収リストシート").Cells(n, 2) Then
            Sheets("検収リストシート").Select
            Range(Cells(n, 1), Cells(n, 14)).Select
            Selection.Copy
            Sheets("データーシート").Select
            Range("a1") = 88
            Range("a2") = 99
            Cells(1, 1).End(xlDown).Offset(1).Select

            ActiveSheet.Paste

            m = m + 1
            'Exit For

        End If
    Next
Next

'横に並べる
For i = 1 To 10
m = 1

    For n = i + 1 To 10
        If Cells(3 + i, 2) = Cells(3 + n, 2) Then
            Range(Cells(3 + n, 1), Cells(3 + n, 14)).Select
            Selection.Cut

            Cells(3 + i, 15 * m).Select
            'ActiveSheet.Paste
            Selection.Insert Shift:=xlToRight
            m = m + 1
        End If
    Next
Next

'空欄詰める
For i = 1 To 10

    If Cells(i, 1) = "" Then
        Rows(i).Select
        Selection.Delete Shift:=xlUp
    End If
Next

End Sub

(ドカ)


 >Bに転記済みのC列管理番号のものもも毎回再検索したいです。 
 ここって、どの様なイメージですか?

 データーシートは毎回新しく作り替えれば良いのかと思いましたが。。。
 そうでもないのでしょうか?

 また、検収リストシートは管理番号毎にグループに成って並んでいる様ですが
 実際もそうでしょうか?

 (HANA)


ドカさん

回答をありがとうございました。

頂いたコードで、会社ではないので同じ環境ではないのですが検証してみましたが
上手く動きませんでした・・。
ずっとまるでループがかかったような状態で、しばらく待ちましたら抜けましたが
データーシートA列に「88」と「99」が表示されていました。

細かい点の修正はご自分でお願いします。 とのことでしたので、ここから完成させねばと拙い知識でコードの解読をしてみたのですが・・。

Range("a1") = 88 Range("a2") = 99 Cells(1, 1).End(xlDown).Offset(1).Select

@これってどういう意味でしょうか?
その前の部分は、管理番号シートのC列と検収リストのB列が一致したら検収リストシートのA列から14列目までをコピーして、貼り付ける際のデータシートへの指定だと思うもですが、勉強不足で88と99がよくわかりません。

Aまた、管理番号シートのC列と検収リストのB列が一致したら下記処理をするというコード?かと思ったのですが。
そうすると、一致しなかった場合には管理番号シートのC列の並び順通りに、
データーシート側に管理番号シートのC列+右列以降は空白にして次の検索へ行きたいのですが、
そのためにはさらに追加で何かコードを記載する必要があるのでしょうか?

B >For n = i + 1 To 10

        >If Cells(3 + i, 2) = Cells(3 + n, 2) Then
            >Range(Cells(3 + n, 1), Cells(3 + n, 14)).Select
            >Selection.Cut
これは、横に並べるというコードとのことですが、
コードがエラーになりましたが一番上のコードは(i+1) To 10 としてよいですか?
その場合、データーシートの5行目B列と4行目B列が同じであったら
4行目A列から4行目の14列目までを選択して切り取りということでしょうか・・。

全く的外れでしたら申し訳ありません。
4行目と5行目を比較としたら1行目、2行目や3行目は?という疑問があります。
ここを自分の仕様に変えればいいのでしょうかね?

本当に初心者なので勘違い、間違いなどしてましたら申し訳ございませんが、
再度教えて頂けますと本当に助かります。

宜しくお願い致します。

(yui)


HANAさん

お返事ありがとうございました。

長文お読み下さり誠に感謝致します。

〉〉Bに転記済みのC列管理番号のものもも毎回再検索したいです。

 >ここって、どの様なイメージですか?

 >データーシートは毎回新しく作り替えれば良いのかと思いましたが。。。
 >そうでもないのでしょうか?

すいません。
私の説明が悪く伝わりきらず申し訳ありませんでした。
ご説明させて頂きます。
上手く伝わるといいのですが・・・。

と、書いていましたら、上記私の記載に間違いを発見しました!!!

〉「また、データシートの管理番号は今月1件であっても来月2件に増えていることがありますので、やはり管理番号シートのC列に記載の番号は毎回再検索したいです。
ただし、2件が1件に減るなど逆はありません。 」

↑↑ここの部分で「データシート」と記載していますが、正しくは「検収リストシート」です。
検収リストもデータがたくさん載っているのでデータシートと言ってしまいました。
本当に申し訳ありませんでした。

改めまして、最終的に転記したいBのデータシートですが・・。
全く新しいものに作りかえるというよりは、過去の情報をどんどん蓄積していくイメージです。
といいますのも、Aの検収リストシートにある項目は、管理番号、会社名、日付、物件番号、予算額とさらに、分割検収1〜12という項目が12列ほどあります。

例えば、
CC-22 という管理番号の予算が100万円であったとして、検収があがるとその検収リストシートにあがってきます。
ただし、その検収のあがり方が1回であがれば2012/1/1 100万とデータに入りそこで終了します。
が、分割検収になる場合が多くあり、1/1に50万検収があがれば、1/2に検収リストシートを出力すると分割検収1の列C列に50万が載ってきます。
この段階で作成予定のマクロを起動すると50万が記載されたものが、データシートC列に転記される。
あと50万が残っていますので、ある程度時期を見て再出力した検収リストデータを元に再度マクロ起動すると検収があがっていれば、その隣の分割検収2のD列に50万が載ってくるというように、どんどんデータシートの右列に日付や検収金額が追加されていくようにしたいのです。(ちなみに今お伝えした列数が質問した数と異なりますが、現在まだ正確な転記列数が未定のためです)

@の管理番号シートC列をキーとしてAのシートから毎回再検索してBのデータシートに上書きすれば、追加された部分のみ追加されて記入されるので、そうしたいです。
Aのシートから前回より追加された部分のみ転記でも同じことですが、ハードル高そうですので毎回丸ごと再検索かけてデータ転記すればいいかなと思いました。

一度検索し、データシートに載せた管理番号のデータ行はそのままずっと載せておく予定です。必要なければ色づけなどして管理。@の管理番号シートも同じで、一度記載したらずっと消さずに残しておきます。新しい番号を検索したければ、最下行へ追加していきます。

同じ管理番号が発生するのは、案件毎に管理番号をふっており、同じ管理番号が複数あるのは同じ案件で2件の会社に発注したら同じ管理番号になり、枝番号か会社名で違いを見分けています。
管理は管理番号ごとにデータを紐づけたいので同じ管理番号のデータであれば、どんどん右に追加していきたいです。
今は1件しか管理番号がなくても、追加発注がかかれば同じ番号で発番し同管理番号が未来に増える可能性があります。

該当データがなかった場合にデーターシート側に管理番号のみA列に記載し右列を空白にしたいのは、
番号が発番されたのがわかっているので、先にデータシートに載せておきたいのです。
他に手入力で記載する列がありますので。

Bのデーターシート側は一旦転記したらそのまま削除することはなく、追加していく表のようなものにする予定です。

ちなみに、実は本当にやりたいのは、@の管理番号シートの横にAの検収リストのデータを転記したいのですが、@のシートが結合セルなので、Aから@の直接転記コードはハードルが高すぎて私には絶対無理なのです><
そのためBのデータシートを作って、後で@に転記しようかと思っているのですが・・。
出来なければBのシートを表にして終わりにしようかな〜と。
ややこしくなるので、最初の質問時の表には結合セルのようには記載していません。

〉また、検収リストシートは管理番号毎にグループに成って並んでいる様ですが
〉実際もそうでしょうか?

↑↑
はい、そうです!!
こちらは、私がCSVで検収リストシートを作成した時点で管理番号の昇順で並び替えるようにしています。
必要ないのかな?とも思いましたが、検証する際に見やすいので、そうしました。

HANAさんにこの説明でおわかりいただけたかどうか自信がありません。
的外れな回答でしたら申し訳ありません。
不明点ありましたらご指摘下さいませ。

そしてまた長文失礼致しました。

困っているので助けて頂けますと本当に助かります。
どうぞ宜しくお願い致します。

(yui)


”ずっとまるでループがかかったような状態で、しばらく待ちましたら抜けましたが”

私のコードは基本的に処理時間が掛かるかもしれません。ただし、初心者でもわかる一番簡単なコードです。トイレに行く間に動かせば終わっていると思います。

ifやforがたくさん出てくると、他人の作ったコードはなんだか分からないと思いますが、作る本人はシンプルなコードをだんだん複雑にしていくので、意外と簡単に作れますよ。

”データーシートA列に「88」と「99」が表示されていました。”

A列の下にデータを追加して行くときに、データの一番下のセルを求めるためにダミーとして、入れました。元々項目名などが入っていれば、わざわざ入れる必要はないですが、とりあえずは大した問題ではないので後で考えましょう。

”Aまた、管理番号シートのC列と検収リストのB列が一致したら下記処理をするというコード?かと思ったのですが。
そうすると、一致しなかった場合には管理番号シートのC列の並び順通りに、
データーシート側に管理番号シートのC列+右列以降は空白にして次の検索へ行きたいのですが、
そのためにはさらに追加で何かコードを記載する必要があるのでしょうか? ”

これは私が勘違いしていました。ご要望のほうが簡単なので、明日また直しておきます。

”B >For n = i + 1 To 10

        >If Cells(3 + i, 2) = Cells(3 + n, 2) Then
            >Range(Cells(3 + n, 1), Cells(3 + n, 14)).Select
            >Selection.Cut
これは、横に並べるというコードとのことですが、
コードがエラーになりましたが一番上のコードは(i+1) To 10 としてよいですか?
その場合、データーシートの5行目B列と4行目B列が同じであったら
4行目A列から4行目の14列目までを選択して切り取りということでしょうか・・。”

(i+1)としても良いです。
提示されたデータをそのまま使って、こちらではエラーは出ないのですが・・・

とりあえず、
GG-44|8/10 |5000 |件2|GG-44-01
GG-44 |8/12|100000|件3|
GG-44|8/14 |200000|件4 |GG-44-03
こんな感じで、最初データを縦に並べるようにしています。

その後、
GG-44|8/10 |5000 |件2|GG-44-01  下から切り取ってここに挿入していきます。
GG-44 |8/12|100000|件3|
GG-44|8/14 |200000|件4 |GG-44-03

GG-44|8/10 |5000 |件2|GG-44-01   GG-44|8/14 |200000|件4 |GG-44-03  
GG-44 |8/12|100000|件3|

GG-44|8/10 |5000 |件2|GG-44-01   GG-44 |8/12|100000|件3|   GG-44|8/14 |200000|件4 |GG-44-03  


 一つの管理番号の行に
  分割検収になったデータや他の会社に発注したデータ
  等のデータがが混在した状態になる
 って事ですか?

 >@の管理番号シートC列をキーとしてAのシートから毎回再検索してBのデータシートに上書きすれば、
 >追加された部分のみ追加されて記入されるので、そうしたいです。 
 >Aのシートから前回より追加された部分のみ転記でも同じことですが、
 >ハードル高そうですので毎回丸ごと再検索かけてデータ転記すればいいかなと思いました。

  ・実行前にデータシートにあるデータはそのままで、続きに追記していく
  ・検収リストシートには、今回転記すべきデータのみがリストになっている 
 って事ですか?

 >他に手入力で記載する列がありますので。 
 データシートに転記してしまったら、検収リストシートのデータではなく
 データシートのデータが正規のデータになるのですか?

 また、手入力で記載する列と言うのは、今回の転記とは全く別の列でしょうか?
 組み込まれている列でしょうか?挟み込んでいく列でしょうか?

 >@のシートが結合セルなので、
 これは、C列以外が結合セルなのでしょうか?
 C列も結合セルだが、そちらで対処する という事でしょうか?

 C列も結合セルの場合、その他の結合セルの状態にもよると思いますが
 直接 管理番号シートに転記した方が
 簡単な場合もあるのではないかと思いますが。。。

 (HANA)

一旦貼り付け (ドカ)
Sub test()
'Dim flg
Sheets("データーシート").Select
    Cells.Select
    Range("A86").Activate
    Application.CutCopyMode = False
    Selection.ClearContents

For i = 1 To 20
m = 0
flg = 0

    For n = 1 To 20
        If Sheets("管理番号シート").Cells(i, 3) = Sheets("検収リストシート").Cells(n, 1) Then
            flg = 1
            Sheets("検収リストシート").Select
            Range(Cells(n, 1), Cells(n, 14)).Select
            Selection.Copy
            Sheets("データーシート").Select
            Cells(Rows.Count, 1).End(xlUp).Offset(1).Select

            ActiveSheet.Paste

            m = m + 1
            'Exit For
        End If

    Next
        'MsgBox i, flg
        If flg = 0 Then
MsgBox i & " " & flg
            Sheets("管理番号シート").Select
            Sheets("管理番号シート").Cells(i, 3).Select
            Selection.Copy
            Sheets("データーシート").Select
            Cells(Rows.Count, 1).End(xlUp).Offset(1).Select

            ActiveSheet.Paste
            flg = 0
        End If
Next

'横に並べる
For i = 1 To 10

    m = 1

    For n = i + 1 To 10
        If Cells(i, 1) = Cells(n, 1) Then
            Range(Cells(n, 1), Cells(n, 14)).Select
            Selection.Cut

            Cells(i, 15 * m).Select
            'ActiveSheet.Paste
            Selection.Insert Shift:=xlToRight
            m = m + 1
        End If
    Next
Next

'空欄詰める
For i = 10 To 1 Step -1

    If Cells(i, 1) = "" Then
        Rows(i).Select
        Selection.Delete Shift:=xlUp
    End If
Next

End Sub


ドカさん

出勤前なので手短に失礼します。

コードの記載ありがとうございます。
私の表現も悪く失礼しました。

検証、コードの読み取りをしてからまたご報告、質問させていただきたいです。
どうぞ宜しくお願い致します。

ありがとうございます。

(yui)


hanaさん

お返事ありがとうございます!
手短に失礼します!

〉一つの管理番号の行に
〉分割検収になったデータや他の会社に発注したデータ
〉等のデータがが混在した状態になる
〉って事ですか?

そうです。ですが、一番上にタイトル行をつけて管理する予定ですので、同じ管理番号であれば同じ行に横並びになっていて問題ありません。

〉・実行前にデータシートにあるデータはそのままで、続きに追記していく
そうです。

〉・検収リストシートには、今回転記すべきデータのみがリストになっている
〉って事ですか?

検収リストシートは前回転記済みのデータ含めて全てが上書きされたリストになっています。
さらに、不要なデータが300くらい載っています。
そこから、今回必要な管理番号のみ抽出、転記したいです。

〉データシートに転記してしまったら、検収リストシートのデータではなく
〉データシートのデータが正規のデータになるのですか?
そうです。
必要なのは転記した後の、検収リストシートから抽出された状態のデータだけなのです。
過去は検収リストシートからオートフィルタ―で抽出してデータシート側にコピペしていたようなのですが、間違いが発生しやすいとのことですので今回VBA化に取り組んでいます。

〉また、手入力で記載する列と言うのは、今回の転記とは全く別の列でしょうか?
〉組み込まれている列でしょうか?挟み込んでいく列でしょうか?
方法を提案していただいたら、転記開始する列を右に変更して、あいている列に挟み込むつもりでした。
まだ、手入力する列数と位置が未定でしたので・・。

〉これは、C列以外が結合セルなのでしょうか?
〉C列も結合セルだが、そちらで対処する という事でしょうか?

C列は2行ごとの結合セルですが、こちらで対処しようと思っていました。
例えば、もう一枚C列を結合していないシートに転記して、そちらとマッチさせるなど・・。
シートが増えてへんで、素人考えですよね><

また夜にでも説明不足がありましたら後で読み返して追記があれば書き込みます。
ありがとうございました!
(yui)


(ドカ)
私が作ったシートのデータの列がずれていたため、最初のコードは動きませんでした。
今度は動くはずです。

プログラムの書き方として、
こうだったらこうして、あれがこうならこうなって、さらにこうならこうで、・・・・と書くと、
後から見た場合や、他人からは、分かりずらいコードになるので、

行数が増えたり、処理時間が掛かったとしても、あえて、このような書いています。
まずこの処理をやる。
これがうまくいくことが確認できたら、
次にこれをやる。
最後にこうする。

Sub test()
'データシートがどんなものか分からないので
'一旦全てのセルをクリアにします。
Sheets("データーシート").Select

    Cells.Select
    Range("A86").Activate
    Application.CutCopyMode = False
    Selection.ClearContents
'ここまで

'繰り返しの10や20は適当な数字です。
For i = 1 To 20 '管理番号シートを一つづつ見ていきます
m = 0 '何個右に足せば良いか数える
flg = 0 '研修リストシートにデータがあるかないか覚えておきます

    For n = 1 To 20 '研修リストシートを一つづつ見ます。
        If Sheets("管理番号シート").Cells(i, 3) = Sheets("検収リストシート").Cells(n, 1) Then
            flg = 1
            Sheets("検収リストシート").Select
            Range(Cells(n, 1), Cells(n, 14)).Select
            Selection.Copy
            Sheets("データーシート").Select
            Cells(Rows.Count, 1).End(xlUp).Offset(1).Select
            ActiveSheet.Paste
            m = m + 1
            'Exit For
        End If
    Next
        'MsgBox i, flg
        If flg = 0 Then
            Sheets("管理番号シート").Select
            Sheets("管理番号シート").Cells(i, 3).Select
            Selection.Copy
            Sheets("データーシート").Select
            Cells(Rows.Count, 1).End(xlUp).Offset(1).Select
            ActiveSheet.Paste
            flg = 0
        End If
Next
'横に並べる
For i = 1 To 10
    m = 1

    For n = i + 1 To 10
        If Cells(i, 1) = Cells(n, 1) Then
            Range(Cells(n, 1), Cells(n, 14)).Select
            Selection.Cut

            Cells(i, 15 * m).Select
            'ActiveSheet.Paste
            Selection.Insert Shift:=xlToRight
            m = m + 1
        End If
    Next
Next
'空欄詰める
For i = 10 To 1 Step -1

    If Cells(i, 1) = "" Then
        Rows(i).Select
        Selection.Delete Shift:=xlUp
    End If
Next
End Sub


 運用イメージがつかめません。
  (まだはっきり確定してない部分も有るかとは思いますが。。。)

 >同じ管理番号であれば同じ行に横並びになっていて問題ありません。
 これは分かりました。

 >検収リストシートは前回転記済みのデータ含めて全てが上書きされたリストになっています。 
 と言う事は、実行前にデータシートに有るデータと照合をして
 転記済みデータか、未転記データかを確認し
 未転記データだった場合のみ、転記すると言う作業が必要に成ってくるのでしょうか?

 >転記開始する列を右に変更して、あいている列に挟み込むつもりでした。
 仮に1レコードが5件(管理番号・日付・金額・枝番号・備考)だったとします。
 タイトルとしては
  [A]       [B]    [C]    [D]      [E]    [F]    [G]    [H]      [I]    [J]    [K]    [L]      [M]
  管理番号 日付1 金額1 枝番号1 備考1 日付2 金額2 枝番号2 備考2 日付3 金額3 枝番号3 備考3 ・・・・

 の様に続くと思いますが、後から手入力するのは
 [A]-[B]の間に、検収リストシートのデータとは関係を持たないデータ なのか
 [E],[I],[M] の様に、検収リストシートにはデータとしてあがらなかったが記入しておきたいデータ なのか
 [E]-[F],[I]-[J],[M]-[N]の間 と言った 実際は検収リストシートに付随しているデータ なのか
 どう言ったデータをどの様に入れるのでしょう?

 >該当しなかった場合はまだ検収があがっていないものなのですが、
 >あがる前でも他の列項目に先に入力しておきたい項目があるので、空白にして、
 >検収があがったらそこにデータが追記できるような仕様にしたいのです。 

 って事は、元々入力されているデータを無条件で残せばよい って事にも成らないんですかね。。。?

 >必要なのは転記した後の、検収リストシートから抽出された状態のデータだけなのです。
 検収リストシート(1)→データシート→検収リストシート(2)
 とデータが流れて行き、検収リストシート(2)が必要??

 もしも一つのシートの中にいくつか表が有るのなら
 ○○シートの××表 の様に書いてもらえると
 話も分かりやすくなるのではないかと思いますし
 シートのレイアウトも分かって良いと思います。

 関係ない様に思っても、コードを作る上で
 その他の部分のシートの状態が関係して来ることも有ります。

 同じ結果を導く為の道筋は無数に有ります。

 >C列は2行ごとの結合セルですが、こちらで対処しようと思っていました。 
 >例えば、もう一枚C列を結合していないシートに転記して、そちらとマッチさせるなど・・。 
 この方法でも同じ結果にする事は出来ると思いますが、2行毎にデータが有る事が分かっているなら
 最初からそれを想定したコードを作った方が無駄が無いです。

 同じ結果に成るなら、読みにくいコードより読みやすいコードの方が良いでしょうし
 程度にもよると思いますが、処理速度が遅いコードより、早いコードの方が良いと思います。

 もう少し詳細な説明をしてもらえませんか?

 ぐだぐだ言っていても仕様が無いので取り敢えず
 以下の状態を想定した簡易コードを作ってみました。
 新しいシートに表を作成して行くものです。
 既に有るデータと照合したり、続きに転記したりはしてません。

 新しいブックに以下のシートを作成し、動かしてみて下さい。

 Sheet1	[A]	[B]	[C]		
[ 1]	管理番号				
[ 2]	EE-33				
[ 3]					
[ 4]	CC-22				
[ 5]					
[ 6]	AA-11				
[ 7]					
[ 8]	GG-44				
[ 9]					
[10]	WW-55				
[11]					
[12]	RR-66				
[13]					
 Sheet2	[A]	[B]	[C]	[D]	[E]
[ 1]	管理番号	日付	金額	枝番号	備考
[ 2]	CC-22	2月1日	1000	CC-22-01	物件1
[ 3]	CC-22	3月1日	10000	CC-22-02	物件2
[ 4]	EE-33	10月2日	20000	EE-33-01	物件A
[ 5]	LL-10	2月4日	350	LL-10-01	物件B
[ 6]	KK-66	3月10日	4000	KK-66-01	案件1
[ 7]	GG-44	8月10日	5000	GG-44-01	案件2
[ 8]	GG-44	8月12日	100000	GG-44-02	案件3
[ 9]	GG-44	8月14日	200000	GG-44-03	案件4
[10]	FD-22	2月3日	50000	FD-22-01	案件5
[11]	FD-22	2月4日	23000	FD-22-02	物件C
[12]	FD-22	2月5日	4000	FD-22-03	物件D
[13]					
 ブラウザ上では、レイアウトが崩れているかもしれませんが
 こちらからコピーして、ワークシートに値貼り付けして下さい。

 '------
Sub TEST()
Dim i As Long, ii As Long
Dim sh1 As Worksheet, sh2 As Worksheet
Dim mxr1 As Long, mxr2 As Long
Dim xc As Long, MyR As Variant
    Set sh1 = Sheets("Sheet1")
    Set sh2 = Sheets("Sheet2")

    mxr1 = sh1.Range("A" & Rows.Count).End(xlUp).Row
    mxr2 = sh2.Range("A" & Rows.Count).End(xlUp).Row

    For i = 2 To mxr1 Step 2 'Sheet1の管理番号を上から順番に処理
            '↓対象の管理番号がSheet2の何行目から始まっているか MATCH関数で調べる
        MyR = Application.Match(sh1.Range("A" & i).Value, sh2.Range("A1:A" & mxr2), 0)
        If Not IsError(MyR) Then    'Sheet2に対象の管理番号が有った場合
            xc = 1
            ii = MyR
            Do      '↓Sheet1に、Sheet2の一行分を転記
                sh1.Range("A" & i).Offset(, xc).Resize(, 4).Value = _
                    sh2.Range("B" & ii).Resize(, 4).Value
                xc = xc + 4
                ii = ii + 1
            Loop Until sh2.Range("A" & ii).Value <> sh1.Range("A" & i).Value
        End If      '↑Sheet2の次の値が、対象の管理番号でなかったら ループ終了
    Next

    Set sh1 = Nothing
    Set sh2 = Nothing
End Sub
 '------

 どの様なコードが理解しやすいかは判断が難しいですが。。。
 なるべく単純なコードに成る様にしてみました。

 実際の運用時、同じ考え方が出来るか 別の方法をとるのが良いか分かりませんが
 そんなに難しく考えなくても出来そうな事を 見てもらえると良いと思います。

 (HANA)

ドカさん

コードのご提示ありがとうございます!
データが会社のため、明日にでも最新のもので考えてみます。

ドカさんのコードで、横に行を並べるために下の管理番号と一致したら
コピーして転記していくというのは目からウロコでした。
そういう着眼点があるんだな、と本当に感心しました。

プログラムの書き方の考え方も教えていただいてありがとうございます。
どうしたらいいかわからなかったんです。

ドカさんのコードでもどういう動きをし、自分の仕様にするにはどうしたらいいか
じっくり考えてみます。
今後もこのような仕事はたくさんあるので・・。

いろいろなパターンをマスター出来るよう頑張ります!
検証してからまた不明点などありましたらまたどうぞお助け下さいませ。

ありがとうございました!

(yui)


HANAさん

お返事ありがとうございました。
私の説明が拙く申し訳なく思っております。

ですが!
提示していただいたシート1とシート2をコピーして
コードを動かしてみました。

すごいです。
私の希望通りの動きをしていました!

きちんとした説明も出来ずに申し訳ありませんでした。
頂いたコードを元に、実際の管理番号のキー列をA列からC列に直したり微調整すればよさそうです。

実際の会社データで動かして問題あればご相談させて頂くかもしれません。
その際は申し訳ないですが、お付き合い下されば幸いです。

ちなみに、頂いた質問に対して遅いかもしれませんが返答させていただきます。

〉〉検収リストシートは前回転記済みのデータ含めて全てが上書きされたリストになっています。

 〉と言う事は、実行前にデータシートに有るデータと照合をして
 〉転記済みデータか、未転記データかを確認し
 〉未転記データだった場合のみ、転記すると言う作業が必要に成ってくるのでしょうか?
↑↑
私は、確認作業は不要で、データシートに転記済みであっても、未転記でも全て最新の検収リストデータで上書きしてしまっていいと思っていました。

〉後から手入力するのは
〉 [A]-[B]の間に、検収リストシートのデータとは関係を持たないデータ なのか
〉 [E],[I],[M] の様に、検収リストシートにはデータとしてあがらなかったが記入しておきたいデータ なのか
〉 [E]-[F],[I]-[J],[M]-[N]の間 と言った 実際は検収リストシートに付随しているデータ なのか

 どう言ったデータをどの様に入れるのでしょう?
↑↑
[A]-[B]の間に、検収リストシートのデータとは関係ないデータです。
具体的には売上達成率何%とか、目標数値とかそういうもので関係ありません。

また、一つのシートの中に表がいくつもあったりはしません。

結合セルの件では最初に伝えておらずご迷惑おかけしました。
結合セルを最初の質問時にお伝えしなかったのは、以前別のサイトで別件で
同じようにVBAの質問をさせて頂いた時にも結セルだったのですが、
その時に結合セル表の件で皆さま方にいろいろご指摘いただきまして・・。

結合セルは初心者には難しいから結合セルを扱わないようなフォーマットにしたほうがいい、
またなぜ結合セルなのかとか結合セルの部分でひどく忠告をいただいたのです><

それで、また今回結合セルを言い出すとその部分で無理だ、
とおっしゃられるのではないかと思い・・。

そのため伝えないで後でなんとかしようと思ってしまったのです。
すいませんでした。

結合していても出来ることはあるんですね。勉強になりました。

とりあえず、コードを読み込んで自分仕様に当てはめてみます。
ありがとうございました。

(yui)


 >全て最新の検収リストデータで上書きしてしまっていいと思っていました。

 >[A]-[B]の間に、検収リストシートのデータとは関係ないデータです。
 >具体的には売上達成率何%とか、目標数値とかそういうもので関係ありません。

 と言う事でしたら、まずは列番号等を調整してやってみてもらって良さそうですね。
 データ量が多いと処理に時間がかかるかもしれませんので
 その際は、もう少し考えてみると良いかもしれません。

 mxr1,mxr2の列番号は、データが有る最終行が埋まっている列を指定して下さい。
 Match関数の中の列番号は、それぞれ管理番号が有る列番号に変えてください。

 今は結果をB列から書き出していますが、別の列にしたい場合は xc=1 の値を
 変更してもらうのが良いのではないかと思います。
 1だったら、B列から。2にしたら、C列から。。。と順にずれていきます。

 が、もしかしたら 列番号を変更してもらった方が
 指折り数えなくて済むので良いかもしれないですね。
 その場合は、転記を開始する最初の列の一つ前の列番号を入れて下さい。
 F列から結果を書き始めるなら、
   sh1.Range("E" & i).Offset(, xc).Resize(, 4).Value = _
 って感じです。

 都度、xcを-1 する事にするなら、最初の列番号で良いです。
   sh1.Range("F" & i).Offset(, xc - 1).Resize(, 4).Value = _

 はっっ、そしたらいっそのこと
   xc = 0
 最初を「0」で始めれば良いじゃん  ってなっちゃいますね。。。

 眺めてみて、分かりやすいと思われる物を選んでもらえると良いと思います。

 転記する元データの先頭はSheet2のB列と言う事にしてありますが
 実際の列番号に変更して下さい。

 転記すべき1レコードの数を今は4件にしてあります。
 2箇所のResizeと、xc = xc + 4 の合計3箇所に出てきますので
 忘れず全て変更して下さい。

 Loop Until の行も、管理番号が有る列番号に変更して下さい。

 もしも 転記データが4件で、間に空列を挟んでいきたい場合は
 xc = xc + 5 にすると、空列が1列入る事になります。

 このあたりの値も、変更して動かしてみて 目で見て確認してもらえると
 分かりやすいのではないかと思います。

 >結合セルは初心者には難しいから結合セルを扱わないようなフォーマットにしたほうがいい、 
 >またなぜ結合セルなのかとか結合セルの部分でひどく忠告をいただいたのです><  
 そうですね。
 データを処理させようとした時、結合セルが無い方が簡単で済む事が多いと思います。
 今回のサンプルも、例えば
  Sheet1は AB,CD,EF,GH,・・・と2列ずつ結合
  Sheet2は、列方向の結合は無し
 等であれば、やはりそれだけ処理は面倒になりますので
 こういった場所では、まず結合解除を薦められると思います。

 こちらからは、そちらの事情が分からないので 察して頂けるとありがたいのですが。。。

 話は戻って
 >全て最新の検収リストデータで上書きしてしまっていい
 ですが、転記済みのシートに上書きしていくなら、処理を開始した時に
 前回のデータを削除するコードを入れておくのが良いかもしれません。

 ざっくりとしたものですが
  sh1.Range("B1:M" & mxr1).Offset(1).ClearContents
 こんな感じで・・・。

 (HANA)

 あ〜、流石に
 sh1.Range("B1:M" & mxr1).Offset(1).ClearContents
 ↑は恥ずかしいので

 sh1.Range("B2:M" & mxr1).ClearContents
 こう言うのが、素直ですよね。。。

 (HANA)

HANAさん

列や転記場所変更の場合の変更位置まで記載いただいて
本当にありがとうございました。

実は、会社で一気に変更しようとしたのですが、
ミスしていたみたいで動かず・・。

でも、HANAさんの教えていただいた変更位置を参考に
一つづつ動きを見て仕様を理解して変更していったら
上手くいきました!

ドカさんから教えていただいたコードもそうですが、
コードの記述を見て考えると理解できるのですが、
自分ではなかなかコードの組み立てを考えるのが難しいですね!

でも今後もこのようなお仕事はいろいろあるので、
頑張っていきたいです。

本当にありがとうございました。

(yui)


 うまく出来ましたか、良かったです。

 >自分ではなかなかコードの組み立てを考えるのが難しいですね! 
 そうですね。
 ですから、似たような事例を見つけた時に
 ・まず自分で考えて書いてみる。

 その後、動かない事を確認して
 ・サンプルコードを見比べて何処が悪いか問題箇所を見つけて修正する。

 を繰り返していると、最初の段階で動くコードが書ける様に成るのではないかと思います。

 >今後もこのようなお仕事はいろいろあるので
 でしたら、仕事が楽になる一方ですから 良いですね。
 楽しみながら、続けて行ってもらえると良いと思います。

 今回の考え方が出来る前提条件
 『検収リストシートを作成した時点で管理番号の昇順で並び替えるようにしています。』
 を忘れない様に、運用して行って下さい。

 もしも、その他の事で並び替えが行われている必要が無いのなら
 今回のコードの近辺で行う様にすると良いかもしれません。

 落ち着いたら、そのあたりも整理して貰えると良いかもしれません。

 (HANA)

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.