• ベストアンサー

エクセルでのVBA(マクロ)

以前Wendy02さまに 以下のようなデータがシート1に入力されているもので   A  B   C    D   E    F  1名前 住所 請求書 納品書 領収書 到着確認書 2山田 東京  ○       ○ 3井上 千葉      ○   ○    ○ 4植田 大阪      ○   ○ 5境  秋田  ○   ○ 6大田 沖縄  ○   ○   ○    ○ 7野原 埼玉          ○ データの”○”は書類が確認済で、空白は未確認あるいは未到着です。 "C"列から"F"列の中で1つ以上空白のあるデータを検索して別シート2へそのままコピー出来るマクロを教えていただいたのですが、 A列に受付番号(500件)を先に入力しておいて(一応自分でマクロを組んで)同じ処理をするとデータ(B列:名前)が入力されていないものまで検索結果としてカウントされます。 Sub FindBlank1() Dim Rng As Range Dim i As Long 'Sheet2のフィールド行(名前,住所..)は、1行目にあるとします。 With Sheet1 .Activate i = 2 '2行目から Set Rng = .Range("A1", .Range("A65536").End(xlUp)) For Each c In Rng  If Application.CountA(c.Offset(, 2).Resize(, 4)) <> 4 Then    'A列から、A列を含めて6列取得し、Sheet2にコピー    c.Resize(, 6).Copy Sheet2.Cells(i, 1).Resize(, 6)    i = i + 1  End If Next End With End Sub >i = 2 '2行目から の前に組めば出来る筈だと思うのですが? お助けください。

質問者が選んだベストアンサー

  • ベストアンサー
  • ham_kamo
  • ベストアンサー率55% (659/1197)
回答No.1

以下のように修正すればいいのではないでしょうか。 Sub FindBlank1() Dim Rng As Range Dim i As Long 'Sheet2のフィールド行(名前,住所..)は、1行目にあるとします。 With Sheet1 .Activate i = 2 '2行目から Set Rng = .Range("B1", .Range("B65536").End(xlUp)) For Each c In Rng  If Application.CountA(c.Offset(, 1).Resize(, 4)) <> 4 Then    'A列から、A列を含めて6列取得し、Sheet2にコピー    c.Offset(,-1).Resize(, 6).Copy Sheet2.Cells(i, 1).Resize(, 6)    i = i + 1  End If Next End With End Sub

hirosatonn
質問者

お礼

>Set Rng = .Range("B1", .Range("B65536").End(xlUp)) やはりAをBに変更するだけでしたか?1度変更してやったつもりなのですが? >c.Offset(,-1) これを忘れていたようです。 ありがとうございました。

その他の回答 (2)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

こんばんは。Wendy02です。 最近は、少し、コードの書き方を変えていますが、私自身としては、#1のham_kamo さんのコードのように書くようになると思います。 つまり、A列は、先に、データのあるなしに関わらず、受付番号として存在してしまっていますから、事実上、1列増えて、B列の名前で、処理しなくてはならなくなったわけですから、正しいデータを取るためには、以下が必要です。  .Range("B1", .Range("B65536").End(xlUp)) ただ、もし、受付番号を含め7列にするのだったら、  c.Offset(,-1).Resize(, 7).Copy Sheet2.Cells(i, 1).Resize(, 7) このようになるかと思います。実際には、今は試していないので、不安がありますが。 何か、ham_kamoさんと、venzoさんの良いとこ取りで申し訳ないです。

hirosatonn
質問者

お礼

いつも回答ありがとうございます。

noname#22650
noname#22650
回答No.2

A列を追加してデータが右にずれたと言うことでしょうか? でしたら、ここの 2 を 3 に変える 誤:If Application.CountA(c.Offset(, 2).Resize(, 4)) <> 4 Then 正:If Application.CountA(c.Offset(, 3).Resize(, 4)) <> 4 Then これでC列から4列空白かどうか判定することになると思います。 ついでに、ここの6を7に 誤:c.Resize(, 6).Copy Sheet2.Cells(i, 1).Resize(, 6) 正:c.Resize(, 7).Copy Sheet2.Cells(i, 1).Resize(, 7) これでA列から7列(G列まで)コピーされると思います。

hirosatonn
質問者

お礼

的確な回答ありがとうございました。

関連するQ&A

  • 検索マクロがおかしくなって原因がわかりません

    Sheet1のA列にはあらかじめ通し番号が1から入っていて、B列3行目からデータを入力していき、データ入力がされているまでの範囲で検索条件を満たすデータをSheet2へ表示させるマクロ実行で、いつしか、Sheet1のB列にデータが入っていないあらかじめ入力済みのA列の番号全てが検索結果として表示されるようになり、原因がわかりません。 お助けください。 Sub 未到着() Dim Rng As Range Dim i As Long Dim Deliveries As Variant Dim h As Long, j As Long Dim DataRows As Long Dim Result As String ''未到着書類(Sheet2)のフィールド行(受付番号、氏名)は、5行目に(設定して)ある With Sheet1 'Sheet1 をオープン .Activate i = 6 '6行目から該当リストを表示させる 'ユーザーフォームによるメッセージ表示 UserForm1.Show vbModeless DoEvents Set Rng = Range("B3", .Range("B65536").End(xlUp)) For Each c In Rng ' "通知書", "受領書", "預り証", "保険証書" の4項目を検索 If Application.CountA(c.Offset(, 9).Resize(, 4)) <> 4 Then 'A列から、A列を含めて14列取得し、未到着書類にコピー c.Offset(, -1).Resize(, 14).Copy Sheet2.Cells(i, 1) i = i + 1 End If Next End With 'メッセージ用のユーザーフォームを閉じる UserForm1.Hide '配列式に格納 Deliveries = Array("通知書", "受領書", "預り証", "保険証書") 'Sheet2 をオープン With Sheet2 .Activate DataRows = Range("A2", Range("A65536").End(xlUp)).Rows.Count + 1 For h = 6 To DataRows '6行目から For j = 11 To 14 '10列目~13列目 If .Cells(h, j).Value = "" Then '調べたセルの文字列0の長さだったら、 '配列より、取り出す Result = Result & ";" & Deliveries(j - 11) End If Next j If Result <> "" Then '結果が空でないなら、N列に貼り付け .Cells(h, 14).Offset(, 1).Value = Mid(Result, 2) Result = "" End If Next h End With End Sub

  • エクセル 2010 マクロ 検索

    http://okwave.jp/qa/q8562170.html 上記質問に追加です。 ※1 'D,E,F,G,H,I,K を検索してD,E,F,G,H,I に検索対象があった時 E,F,G,H,Iのいずれかだったら左横列の上に向かって (EならD 、FならE ・・・という具合に) 何か入力されているセルのM列の191000####をmsgboxで表示させたいです。 (画 F11セル(A-1)が検索ヒットした場合E9セル(R-01)を辿り、 その行のM列のセル(191000####)をmsgboxで表示 ※2 但し、検索結果がD列のデータだった時、その行のM列が191000####だった場合 M列の191000####をmsgboxで表示させたいです。 (画 D25セル(Y-1)対象の時) ※3 また、検索結果がD列のデータだった時、その行のM列が191000####以外だった場合 (空白だったり191000####以外の場合) M列の一番上の191000####をmsgboxで 191000####&「これは例外です」と表示させたいです。 (画 D24セル (X-1)対象の時) 現在のコードは下記のとおりです。 Sheet1に Private Sub Worksheet_SelectionChange(ByVal Target As Range) If Target.Address <> "$A$3" Then Exit Sub Call 検索 Range("A1:A2").Clear Range("A1").Activate End Sub 標準モジュールに Sub 検索()  Dim Ws1 As Worksheet, Ws2 As Worksheet  Dim strKey As Variant  Dim s As String  Dim c As Range, bln As Boolean  Dim rng1 As Range  Dim cnt As Long    Set Ws1 = Sheet1  Set Ws2 = Sheet2    Ws1.Select    With Ws2   strKey = Application.Transpose(.Range("A1").Resize(2).Value)   strKey = Join(strKey, "")  End With    If Trim(strKey) = "" Then MsgBox "検索キーが空です", vbCritical: Exit Sub      With Ws1   Set rng1 = .Range("K2", .Cells(Rows.Count, "K").End(xlUp))   For Each c In rng1.Offset(, -10)     'D,E,F,G,H,I,Kを検索    s = c.Offset(0, 3).Value & c.Offset(0, 4).Value & c.Offset(0, 5).Value & c.Offset(0, 6).Value & c.Offset(0, 7).Value & c.Offset(0, 8).Value & c.Offset(0, 10).Value &        If StrComp(s, strKey, vbTextCompare) = 0 And c.Offset(0, 2).Value = "" Then     c.End(xlToRight).Activate c.Offset(0, 2).Value = Date          c.Resize(1, 14).Interior.ColorIndex = 6     bln = True     Exit For    End If   Next c      If Not bln Then    Ws2.Select    MsgBox "リストに存在しません", vbExclamation, "NotFound"   Else '加える    Call ReSearch(Ws1.Range("M2"), c.Row)    '再設定    Set rng1 = .Range("K6", .Cells(Rows.Count, "K").End(xlUp))    MsgBox "残り" & DoubleCountBlank(rng1.Offset(, -8), rng1) & "品目です。", vbInformation   End If  End With  Application.Goto Ws2.Range("A1"), True End Sub Sub ReSearch(Rng As Range, j As Long) '最初のセル, 終わりの行数 Dim i As Long Dim Ws As Worksheet With Rng.Parent For i = j To Rng.Row Step -1 If CStr(.Cells(i, Rng.Column).Value) Like "191000####" Then MsgBox "指図番号 " & vbCrLf & CStr(.Cells(i, Rng.Column).Value) & " の部品です" Exit For End If Next i End With End Sub Function DoubleCountBlank(rng1 As Range, rng2 As Range) '横並びのセルのブランクをカウントする (セル範囲1 , セル範囲2)  Dim i As Long  Dim cnt As Long  For i = 1 To rng1.Rows.Count   If VarType(rng2.Cells(i, 1)) = vbDouble Then    If rng1.Cells(i, 1).Value = "" And rng2.Cells(i, 1).Value <> 0 Then     cnt = cnt + 1    End If   End If  Next i  DoubleCountBlank = cnt End Function 宜しくお願い致します。

  • エクセルVBAマクロの質問です。

    マクロ初心者です。 データ処理のマクロを作ろうとしていて、ちょっと困ってます。 (sheet1) 11 国総 1A (空きセル ) 12 化基 2I (空きセル) ・ 以下、200程度のデータ C列のデータの種類は10種類 (sheet2) 1A 2 101 102 2I 3 103 104 105 ・ ・ sheet1のC列と同じデータ C列より右側のデータ数は1から4個程度 (sheet3) データなし sheet1のデータを、sheet3にコピーする際に、各データのD列に、sheet2のC列の右側のデータを入れていきたいんです。具体的には (sheet3) 11 国総 1A 101 11 国総 1A 102 12 化基 2I 103 12 化基 2I 104 12 化基 2I 105 っていう感じです。先日、こちらのカテゴリでなく、間違えてVBAプログラムの方に質問して、「板違いですよ」と諭されながらも、ご協力いただきsheet2の件数分増やしてコピーするコードまではたどり着いたのですが、その後、どうすればD列に移せるのかで悩んでます。ちなみに、いまたどりついたコード文は以下の通りです。 一度、このコード文の続きで、sheet3のC列を条件カウントするコードを作ってみたんですが、動いてくれませんでした。 Sub Re8928577a() Dim M4 As Range Dim P As Variant ' WorksheetFunction.VLookup Dim Kensaku As String Dim L As Long Dim PRow As Long Dim i As Long Dim Z As Long   Set M4 = Sheets("Sheet2").Range("A1:B30")   L = Sheets("Sheet1").Cells(Rows.Count, "A").End(xlUp).Row '   For Z = 1 To L - 1     Kensaku = Sheets("Sheet1").Cells(Z + 1, 3).Value     P = WorksheetFunction.VLookup(Kensaku, M4, 2, False)     PRow = Sheets("Sheet3").Cells(Rows.Count, "A").End(xlUp).Row       For i = PRow + 1 To PRow + P         Sheets("Sheet1").Rows(Z + 1).Copy Sheets("Sheet3").Rows(PRow + 1).Resize(P) Next i   Next Z End Sub

  • エクセルでの複数VBAの作業

     こんばんは。  お世話になります。  以下のコードをMicrosoft Visual Basicの「標準モジュール画面」にて記述し、作動させてみたのですが、  2つ目のSub lll()のみしか反映されないようで、”S”行のみしか値がえられませんでした。  何が問題なのか、初心者のわたくしには、わかりません。  お手数ですが、原因等をお教えいただければ、幸いでございます。 Sub hhh() Dim n As Long Dim rng As Range n = 2000 ReDim hh(1 To n, 1 To 1) Set rng = Range("C2:C31") For i = 1 To n hh(i, 1) = WorksheetFunction.Max(rng) Set rng = rng.Offset(30) Next i Range("R2").Resize(n) = hh End Sub Sub lll() Dim n As Long Dim rng As Range n = 2000 ReDim ll(1 To n, 1 To 1) Set rng = Range("D2:D31") For i = 1 To n ll(i, 1) = WorksheetFunction.Min(rng) Set rng = rng.Offset(30) Next i Range("S2").Resize(n) = ll End Sub

  • VBAの記録を追加したい

    エクセル2002使用です。 VBAで次のコードを使っています。 Private Sub Worksheet_Change(ByVal Target As Range) Dim Rng As Range Set Target = Intersect(Range("C:C"), Target) If Target Is Nothing Then Exit Sub For Each Rng In Target If Rng.Value <> "" Then Rng.Offset(, -2).Value = Now Else ' (*) Rng.Offset(, -2).Value = "" ' (*) End If Next Rng End Sub (C列のセルに何か入力されると、A列の同じ行にその時刻が入る。) 同じシートで、F列に何か入力されるとE列の同じ行にその時刻が入るように書き直したいのですが、どうすればいいのでしょうか? すいませんが、よろしくお願いします。

  • VBAコピー範囲について教えてください。

    VBAのコピーペーストの下記プログラムで、 Sub コピー() Dim rng As Range Set rng = Worksheets("2").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0) With Range("b2:J10") rng.Resize(.Rows.Count, .Columns.Count).Value = .Value End With End Sub コピー範囲 のJ10の部分(データ入力行)が、その都度変わるため、J10の部分を、 J列のデータが入力されている最終行としたいのですが、どのようなプログラムに すればよいのでしょうか。 どなたかよろしくお願いいたします。

  • エクセルのマクロについて教えてください

    お世話になっております。 エクセルのマクロについて教えていただきたいのですが、 サンプルのファイルをこちらにアップしたのでよろしければご覧になってください。 http://kie.nu/yPV 質問したいことは、列Iに、各行の黄色いセルの数を表示させるマクロを作りたいのですが 途中まで何とかわかったのですがどうもうまくいきません。。 行11から各行にひとつずつ、黄色いセルが含まれていますが、その黄色いセルの中の数字を列Iに表示させたいです。行にデータがある限り、下までずっとです。 以下、途中までわかったマクロです。 Sub 黄セル値Copy() Const TgLeftUp = "A3" '<--対象範囲左上セル指定 Dim Rng As Range Dim Target As Range Set Target = Range(TgLeftUp, Cells(Rows.Count, _ Range(TgLeftUp).Column)) For Each Rng In Target.Resize(, 2) If Rng.Interior.ColorIndex = 6 Then If Rng.Column = Target.Column Then Rng.Offset(, 3).Value = Rng.Value Else Rng.Offset(, 2).Value = Rng.Value End If End If Next MsgBox "値 貼り付け完了。", vbInformation Set Target = Nothing End Sub でもこれを貼り付けてもうまくいきません。 正しいマクロを教えていただけないでしょうか?? 宜しくお願いいたします。 ※いつも、私の質問に対してまるで回答になってないような、ふざけた言葉を書き込んでは消してる方が一名だけいらっしゃいます。確か、鳥の写真をマイページに載せてる方です。 都度違反報告はしていますが、質問の趣旨に反する回答をされてる方一名、絶対にやめてください。

  • エクセルVBA抽出がうまく出来ません

    エクセル2013VBA初心者です。 入力シートからDBシートへ、DBシートから印刷シートへのデータ転記と印刷、入力内容のクリアまでは出来るようになりました。 DBシートの検索を行い、記録内容を入力シートに転記する抽出を行いたいのですが、下記構文を書いたところで問題が発生しました。 If Sh2.Range("A & i").Value = j And Sh2.Range("B & i").Value = k Then  でとまります。メッセージは ‘Range’メソッドは失敗しました:‘Workshieet’オブジェクトというものです。 やろうとしていることは、入力シートに設けた“E12”と”G12”の二つの検索項目をキーにDBシートの行を特定し、この行の内容を入力シートに反映しようということです。 入力シートの検索項目“E12”、 ”G12”はそれぞれDBシートのA列、B列に格納されている項目で、年度と連番です。サンプルとして入力シート"C5"に抽出しようとしているDBシートD列は申請者名です。 恐れ入りますがよろしくご教示頂きたく、お願い申し上げます。 Sub DBシートから力情報を抽出する () Dim Sh1 As Worksheet Dim Sh2 As Worksheet Dim i As Long Dim j As Long Dim k As Long Set Sh1 = Worksheets("入力") Set Sh2 = Worksheets("DB") j = Sh1.Range("E12").Value k = Sh1.Range("G12").Value With Sh2 For i = 2 To .Range("A" & Rows.Count).End(xlUp).Row If Sh2.Range("A & i").Value = j And Sh2.Range("B & i").Value = k Then Sh1.Range("C5").Value = Sh2.Range("D & i").Value End If Next  End With End Sub

  • マクロのソートについて

    A列:E列のセルデータがあって、空欄を省いて、コピペでるようにしたのでが、新たに、D列を最初にソート、後からB列・C列を連動させてソートしたいのですが、うまく処理できません。ご教授願えませんか。Sheets("ZZZZZZZ")のデータは1行おきのようなデータです。コピペまではできていますが、その後のソートについてお願いします。 Sub Macro1() Application.ScreenUpdating = False Dim Rng As Range Dim LastRow As Long '●ここをだけ"B2:B100"指定する For Each Rng In Sheets("ZZZZZZZ").Range("B2:B100") If Rng.Value <> "" Then LastRow = Sheets("QQQQQQQQ").Cells(Rows.Count, "B").End(xlUp).Row Sheets("QQQQQQQQ").Cells(LastRow + 1, "B").Resize(1, 3).Value = Rng.Resize(1, 3).Value End If Next Rng Application.CutCopyMode = False Application.ScreenUpdating = True End Sub

  • エクセルVBAで月別最大値を取得したい

    いつもお世話になっております。 要件がエクセルVBAで・・という事で困っています。エクセルの2010を使用しています。 今、添付画像のように、A列に日付、B列に金額が入っており、D列に月表示、E列に各月の金額MAXを入れたいのですが、どのように記述したら良いかわかりません。 調べてみたところ、月の切り替わりに空白が挿入されていれば、下記ソースで月毎のMAXが 抜けることが分かりました(D、E列への転記はわかりませんでしたが・・)。 Sub test1() Dim Rng As Range Dim c As Range Set Rng = Range(Range("B1"), Cells(Rows.Count, Range("B1").Column).End(xlUp))_ .SpecialCells(xlCellTypeConstants) For Each c In Rng.Areas c(c.Count).Offset(1).Value = WorksheetFunction.Max(c) Next End Sub データを抜きたいファイルおよび、シートが大量にあり、とりあえずsheet(1)だけでも 何とかしたいのですが、方法がわかりません。Accessならば集計クエリでグループ化、 最大値を抽出してやればいいのですが。 ご教示いただけますでしょうか。 宜しくお願い致します。

専門家に質問してみよう