[[20160616145457]] 『ブック間の任意列の条件付きコピー』(T1606) ページの最後に飛ぶ

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

 

『ブック間の任意列の条件付きコピー』(T1606)

お世話になります。
Aブックのシートaの任意の列をBブックのシートbのA1以降に条件付きで
「値コピー」する方法をご教授願います。
条件)
コピー対象列に「空欄」と「*」がある場合、その行全体を対象外とします。
説明)
シートa(A1:E6)のB,D列を値コピーする場合、シートbとなります。

 シートa
 A	B	C	D	E
 30	EA	*	3.3 	3.3 
 10	*	AW	3.5 	 
 40	EA	AX		4.8 
 10	*	AJ	2.5 	2.5 
 50	EC	AR	3.7 	3.7 
 シートb				
 B	D			
 EA	3.3 			
 EC	3.7 	

シートaはCSV形式でデータは50列X50万行まで、コピー列20程度を
想定しています。
よろしくお願いします。

追記)
データが多いので、処理時間とマクロ作成手間を考慮いただけると
嬉しいです。

< 使用 Excel:Excel2010、使用 OS:Windows7 >


値コピーって、イコール記号でセル代入するだけでしょう? 面倒なだけで、難しくないと思います。
何処が判らないのか知りませんが、それを調べて作って試すのが貴方の仕事では?

 Sub test()
    Dim wk1 As Workbook
    Dim wk2 As Workbook
    Dim sh1 As Worksheet
    Dim sh2 As Worksheet
    Dim i As Long
    Dim j As Long
    Dim jMax As Long
    Dim iR As Long
    Dim vw As Variant

    Application.ScreenUpdating = False

    vw = Array("B", "D")
    jMax = UBound(vw)

    Set wk1 = Workbooks.Open("c:\test\Book1.xlsx", False, True)
    Set sh1 = wk1.Sheets(1)
    Set wk2 = Workbooks.Open("c:\test\Book2.xlsx")
    Set sh2 = wk2.Sheets(1)

    For i = 1 To sh1.Cells(sh1.Rows.Count, "A").End(xlUp).Row
        For j = 0 To jMax
            If sh1.Cells(i, vw(j)).Value = "*" Or sh1.Cells(i, vw(j)).Value = "" Then
                Exit For
            End If
        Next j
        If jMax < j Then
            iR = iR + 1
            For j = 0 To jMax
                sh2.Cells(iR, j + 1).Value = sh1.Cells(i, vw(j)).Value
            Next j
        End If
    Next i

    wk2.Save
    wk2.Close
    wk1.Close False

    Application.ScreenUpdating = True
 End Sub
(???) 2016/06/16(木) 15:41

(???)様、 早々にありがとうございます。

最初にアップされていたコードではうまくいかず、
原因がわからず再質問しようとしていたところでした。

現コードで問題ないのを確認できましたので、コードの理解を深めて
自宅で実際のデータへ展開したいと思います。

これからも、よろしくお願いします。
(T1606) 2016/06/16(木) 17:40


提示いただいたコードの理解に努めていますが、「If jMax < j Then」の
ところでつまづいています。

私にはなぜこの記述が成立するのか理解できませんでしたが、最初から
ステップインで確認すると直前のJ値が「1」から「2」に変わります。

これなら納得なんですが、なぜ繰上がるのでしょうか???

基本がわかっていないのは重々承知の上で、教えていただけないでしょうか?
(T1606) 2016/06/17(金) 11:43


よいところに気づきましたね。そこはVB熟練者の技の部分です。

For文の仕様として、ループを抜ける際、ループ変数は最後の数字の次になるという仕様なのです。昔のBasicから不変の動作になります。
この性質を、ループの中で条件に該当するものがあったか?、という判定に利用しています。

例えば、For i = 0 To 1 の場合、条件一致するとExit Forしていますよね。すると、iの値は0か1です。
条件一致しなかった場合、For文の動作で、1の次、つまりiは2になります。

これを知らないと、条件一致していたらフラグ変数に値をセットし、ループを抜けた際にチェック、というコーディングになります。知っていれば、変数も代入も減らせる訳ですね。
(???) 2016/06/17(金) 12:03


おまけの練習問題。以下のコードで、表示されるiの値は幾つになると思いますか?
予想してから実行してみてください。これでFor文が完璧に理解できるかと思います。

 Sub test()
    Dim i As Long

    For i = 5 To 1 Step -2
    Next i

    MsgBox i
 End Sub
(???) 2016/06/17(金) 13:08

???様、 再々ありがとうございます。

 >For文の仕様として、ループを抜ける際ループ変数は最後の数字の次になる

そうでしたか..まったく知りませんでした。
「最後の数字の次」の「次」は「次のステップ」なんですね、ご想像通りに
見事にやられましたよ、練習問題に(笑)

キチンと?学習したこともなく主にこのサイトで得たことを頼りの“実戦”だと
どうしてもこういうところでつまづいてしまいますね、メッキが剥がれるというか..(涙)

私には、こういう機会を“肥し”にして積み上げていくしかないですけど。

これからもよろしくお願いします。 楽しかったです。

(T1606) 2016/06/17(金) 13:35


コメント返信:

[ 一覧(最新更新順) ]


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