• 締切済み

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

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

みんなの回答

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

こんにちは。 やっぱり読みきれないですね。たぶん、人が作ったものを変えたものだと思いますが、変なところがいくつもあります。 例えば、 .Cells(h, 14).Offset(, 1).Value = Mid(Result, 2) なぜ、こうなるのでしょうね。ワンセルに全部入れるということでしょうか?一個ずつセルに入れてくれれば問題はないでしょうけれども。 この部分の貼り付けの結果をちょっと調べてみてくださいませんか? 今のコードでは、前の部分の If Application.CountA(c.Offset(, 9).Resize(, 4)) <> 4 とは合わないです。 やむをえないけれども、CountIf で、4つの文字を数えるしかないですね。コードとしては見にくくなってしまいますが。それも、Countif(範囲,"*通知書*") >0 というようなスタイルになります。 そうでないなら、その貼り付けを、Split を使って、分けて、セル一個ずつに入れるかです。ただし、セルの余裕があればの話しです。 ret =Split(Mid(Result, 2),";") .Cells(h, 14).Offset(, 1).Resize(,Ubound(ret)+1).Value =ret いままで出来ていたなら、何かの都合で書き換えましたね。 どういう理由か、なぜか、いきさつを思い出してみてください。こちらでは、その優先順位が分かりません。

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

訂正 >CountA とは、セルに何か、数値でも文字列でも入っていれば、1と数えるものです。 数が少なければ、Copy されるなら、CountA をCount に変えても、減るわけだから、そうではなさそうです。だから、私の#1 は、間違いですね。 どうも、その部分は、私が1年前ぐらい書いた部分ですね。 http://oshiete1.goo.ne.jp/qa2487829.html ただし、やっぱり、 < 4 になっていましたし、Application.CountA ではなくて、WorksheetFunction.CountA でしたけれども。(なぜ、そうするかというと、エラー値が入ったときに、実行時エラーにするからです。Application.CountA ですと、エラー値はエラー値のままです。) そうすると、どこが違う部分なのでしょうか?こちらで、想像して探すのは、ちょっときついですね。 正直言って、プロシージャの途中で、UserForm1.Show をして、また途中で、UserForm1.Hide っていうのは、ちょっと考えられない内容なんですね。 p.s.2007/5月 以降の質問は、一応、終えたと思うものは締めてしまったほうがよいですよ。

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

こんにちは。 >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 Application.CountA(c.Offset(, 9).Resize(, 4)) この部分で、正しく、値が返っているかチェックはしてみましたか? たぶん、4セルですから、「 < 4」 だとは思いますが、 「"通知書", "受領書", "預り証", "保険証書" の4項目を検索」を検索するのに、 と 「<> 4」で済むわけはないですね。これでは、何を検索しているのか良く分かりません。 数値なのですか? CountA とは、セルに何か、数値でも文字列でも入っていれば、1と数えるものです。 その部分を吟味したほうがよいのではありませんか? 一般的には、Count で検索したほうが良いように思います。

関連するQ&A

  • エクセル 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 宜しくお願い致します。

  • エクセル 最終行からの連続コピー

    エクセルで最終行から上に連続する10行(最終行含む)をコピーしたいです。 途中、空白行が含まれている場合でも、最終行を特定し、コピーできるようにするには、下記のコードにどう手を加えたらよいでしょうか? どなたかアドバイスをお願いします。 Sub Test()   Dim i As Long   Dim j As Integer   Dim rng As Range   With ActiveSheet     'フィルタ     .Range("A1").CurrentRegion.AutoFilter Field:=1          '行選択     With .AutoFilter.Range       For i = .Cells(.Cells.Count).Row To 2 Step -1         If .Rows(i).Hidden = False Then           If rng Is Nothing Then             Set rng = .Rows(i)           Else             Set rng = Union(rng, .Rows(i))           End If           j = j + 1         End If         If j >= 10 Then Exit For       Next i       'コピー       If Not rng Is Nothing Then         rng.Copy Worksheets("Sheet2").Range("A1")         Beep       Else         MsgBox "該当行は存在しません。", 48       End If     End With   End With   Set rng = Nothing なお、コードはこちらを参考にさせていただきました。 http://okwave.jp/qa3552420.html?ans_count_asc=1

  • マクロ for~next うまくいかない

    シート内の値を並び替えて、別シートに貼り付けるコード作成中。 ①偶数行の値を奇数行の特定の列に貼り付け、元の値は消す ②(2)と書かれたセルがある場合、その行をコピーして同一行に挿入し、(2)の値は消す この2つが機能しません。 ほか部分は動きます。 これが機能しない原因、分かるでしょうか。 以下、コード Private Sub CommandButton6_Click() Dim i As Long For i = 1 To 9 If Me.Controls("TextBox" & CStr(i)).Value = "" Then 'ユーザーフォーム内のテキスト1~9で空欄があると以下の操作 MsgBox Me.Controls("Label" & CStr(i)).Caption & " が未記入です" '空欄があると、ラベル名+が未記入ですのメッセージ後、処理終了 Exit Sub End If Next Dim Convert_book As String, GC_book As String, GC_address As String Convert_book = TextBox8.Value '変換シートのブック名を取得 GC_book = TextBox7.Value 'ブックAの名前を取得 GC_address = TextBox6.Value 'ブックAの保存先を取得 With Workbooks(GC_book).Worksheets(ws_name) 'ブックAシート1をWithとする。   .Range("A1:CZ200").UnMerge 'ブックAシート1の結合を解く '部品番号と客先コードをコピー .Range(Cells(Range(Parts_no).Row, Range(Parts_no).Column), _ Cells(Range(Parts_no).Row + 1, Range(Parts_no).Column)).Copy '変換シートに貼付けWorkbooks(Convert_book).Worksheets(1).Range("G4").PasteSpecial Paste:=xlPasteValues '管理№をコピー、変換シートに貼付け .Range(Control_no).Copy Workbooks(Convert_book).Worksheets(1).Range("AJ2").PasteSpecial Paste:=xlPasteValues Dim r As Long, r1 As Long, c As Long, c1 As Long, c2 As Long, c3 As Long '管理№の行と列を取得 r = .Range(Control_no).Row c = .Range(Control_no).Column '材料関連の情報のコピーと貼付け .Range(.Cells(r + 2, c - 4), .Cells(r + 3, Last_column - 1)).Copy Workbooks(Convert_book).Worksheets(1).Range("AF4").PasteSpecial Paste:=xlPasteValues '変数に、加工工程№の行と列を入れる。変更年月日の行、測定具の列、管理№の列も入れる。 r = .Range(Process_no).Row '可変 r1 = .Range(Rev_no).Row '可変 c = .Range(Process_no).Column '32または33列目 c1 = .Range(Tool_name).Column '27または28列目 c2 = Last_column '44または43列目 c3 = .Range(Control_no).Column '通常1列目 .Range(Cells(r, c2), Cells(r1 - 2, c2)).Clear '最終列をすべてクリア Dim k As Long, j As Long k = 1 '最終列に1、2、1、……繰返し数を入れる For i = r To r1 - 2 If k = 1 Then .Cells(i, c2).Value = 1 k = k + 1 Else .Cells(i, c2).Value = 2 k = k - 1 End If Next Dim i1 As Long, k1 As Long, j1 As Long k1 = 1 '管理値の欄で偶数列の値を奇数列に移す For i1 = r To r1 - 2 If .Cells(i1, c2).Value = 2 Then For j1 = c3 + 18 To c1 - 1 If .Cells(i1, j1).Value <> "" Then .Cells(i1 - 1, c3 + 25) = .Cells(i1, j1).Value .Cells(i1, j1).Value = "" End If Next j1 End If Next i1 Dim i2 As Long, k2 As Long, j2 As Long k2 = 1 '"(2)"と書いてある行を2行に増やして、"(2)"を消す For i2 = r To r1 - 2 If .Cells(i2, c2).Value = 1 Then For j2 = c3 + 18 To c1 - 1 If .Cells(i2, j2).Value Like "*(2)*" Then .Cells(i2, j2).Formula = Replace(Cells(i2, j2).Formula, "(2)", "") .Range(Cells(i2, 1), Cells(i2, c2)).Copy .Range(Cells(i2, 1), Cells(i2, c2)).Insert xlShiftToRight End If Next j2 End If Next i2 '最終列の番号順に並べる .Range(Cells(r, 1), Cells(r1 - 2, c2)).Sort _ key1:=Cells(r, c2), order1:=xlAscending End With ~~(この間はまだ未作成)~~ Application.DisplayAlerts = False Workbooks(GC_book).Close SaveChanges:=False Application.DisplayAlerts = True End Sub

  • エクセルでの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行目から の前に組めば出来る筈だと思うのですが? お助けください。

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

    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 検索して一致したセルへジャンプさせたい

    Excelにて、シート1のA列とシート2のA列のデータにNoを入れます。 シート1のA列のNoをクリックすると、シート2のA列の同じNoにジャンプするマクロを組みたいです。 現在組んでいるマクロは、 Private Sub Worksheet_SelectionChange(ByVal Target As Range) Dim Sht As Worksheet Dim Rng1 As Range Dim Rng2 As Range Dim FindCell As Range Set Sht = Worksheets("シート2") Set Rng1 = Range("A2:A100") Set Rng2 = Sht.Range("A2:A100")If Intersect(Target, Rng1) Is Nothing Then Exit Sub If Target.Count > 1 Then Exit Sub Set FindCell = Rng2.Find(Target.Value) If Not FindCell Is Nothing Then Application.Goto Reference:=FindCell, Scroll:=False End If End Sub です。 一応マクロは実行されますが、そうすると、シート1のA列の編集(Noを追加したり変更したり・・・)できません。 編集や変更もできて、検索マクロも実行できるというマクロの組み方はありますでしょうか?

  • 調子よく使用していたコードが、急にエラーに!

    Windows XP Home Edition Excel 2002 つい最近、ご回答して頂いたコードです。 オートフィルタ(▼)がかかった、直上のセルに色を付けるために使用しておりました。 どの行でも、どこでも実行できておりました。 大変、調子がよく使用していたのですが、 本日、下記のようにエラーとなり、動作しなくなってしまいました。 原因の一つは、 当方が、 EntireRowにてオートフィルタ(▼)をかけた場合に、 1、 256列全てにオートフィルタ(▼)がかかる。 2、 Range("A1").CurrentRegionのようにデータがある列までオートフィルタ(▼)がかかる。 のように、2通りの結果となります。 1の時にエラーとなるようです。 Range("A1").CurrentRegion にてオートフィルタ(▼)をかけた場合は、 下記コードはきちんと動作します。 1となってしまうのは、当方の、ブックに何か原因があるのでしょうか。 1の場合でも動作させることはできますでしょうか。 当方のデータシートは、データがとんでいる所がありますので、 Range("A1").CurrentRegionでうまくオートフィルタ(▼)がかからない場合があります。 下記★箇所がエラーとなります。 一般的ではない質問かと思いますが、 何卒、ご教示お願い致します。 '------------------------------- 実行時エラー'424' オブジェクトが必要です。 と表示されます。 '------------------------------- Sub Worksheet_Calculate() Static rng As Range   Dim i As Long   Dim j As Long   If ActiveSheet.AutoFilterMode Then     With ActiveSheet.AutoFilter       If .Range.Rows(1).Row = 1 Then 'タイトル行が1行目の場合         j = 0       Else         j = -1       End If       For i = 1 To .Range.Rows(1).Cells.Count         If .Filters(i).On Then           .Range.Rows(1).Offset(j, i - 1).Interior.ColorIndex = 33         Else           .Range.Rows(1).Offset(j, i - 1).Interior.ColorIndex = xlNone  '★         End If       Next i       Set rng = .Range     End With   Else     If Not rng Is Nothing Then 'リセット(ただしできないことがある)       rng.Rows(1).Offset(j).Interior.ColorIndex = xlNone     End If     Set rng = Nothing   End If End Sub

  • 赤いテキストのみを削除したい

    https://okwave.jp/qa/q9543301.html の続きになりますが、宜しくお願いします。 「色を指定しているセルのみ値を削除」 https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1489525229 検索しましたところ、上記を見つけました。 下記のコードに組み合わせましたが、反映されませんでした。 どこが違うのでしょうか? 宜しくお願いします。 Sub test4()   Dim Rng As Range, blanks As Range   Dim ar As Range, 列 As Long   Dim 開始行 As Long, 最終行 As Long, 最終列 As Long   On Error GoTo ErrorHandler     ActiveSheet.Name = "Sheet1"     開始行 = 2   最終行 = Cells(Rows.Count, "A").End(xlUp).Row   最終列 = Cells(開始行, Columns.Count).End(xlToLeft).Column   For 列 = 1 To 最終列     Set Rng = Range(Cells(開始行, 列), Cells(最終行 - 1, 列))     Rng.VerticalAlignment = xlTop     Rng.Borders.LineStyle = xlContinuous ' 黒枠配置     Set blanks = Rng.SpecialCells(xlCellTypeBlanks)     For Each ar In blanks.Areas       Union(ar(1).Offset(-1), ar).Merge     Next ar   Next 列   Cells(最終行, "A").ClearContents ' 赤いテキスト削除  For 列 = 1 To lasrow  If Rng.Font.ColorIndex <= 3 Then Rng.Value = ""  Next ErrorHandler:   If Err Then MsgBox "Error Number = " & Err.Number & Chr(13) & _     "Error Message = " & Err.Description, , "Debug" End Sub

  • エクセル 最終行からの連続コピー

    * すぐに回答を! エクセルC20からI51までデータを1日1行ずつ入力します。 データが入力されている最終行から上に連続する10行(最終行含む)をコピーしたいのですが、最終行から10行上をどのように認識させたらいいのか、わかりません。Offsetなど試してみましたがダメでした。 よろしくお願いします。 Sub dataコピー() Dim i As Long Dim j As Integer Dim rng As Range '最後尾から10行前までを選択 With Worksheets("月").Range(Cells(20, 3), Cells(51, 10)) For i = Cells(Rows.Count, 1).End(xlUp).Row To -10? If rng Is Nothing Then Set rng = .Rows(i) End If j = j + 1 If j >= 10 Then Exit For Next i 'コピー If Not rng Is Nothing Then rng.Copy Range("M1") Beep Else MsgBox "該当行は存在しません。", 48 End If End With Set rng = Nothing End Sub コードはこちらを参考にしました ​http://questionbox.jp.msn.com/qa5440189.html

  • Excelマクロについて

    先日、OKWEBで教えてもらったマクロに手を加えて作ろうとしたのですが、エラーがでて動かなくなりました。 わかる方がいましたら教えてください。 よろしくおねがいします。 Sub 見積書() Application.ScreenUpdating = False '見積書(完成)シートを選択 Sheets("見積書(完成)").Select '行の高さを「15」にする。 Rows("6:67").Select Range("F6").Activate Selection.RowHeight = 15 'S列のS6:S56をコピーしてE6:E7に貼り付ける。 Range("S6:S56").Select Selection.Copy Range("E6:E7").Select ActiveSheet.Paste '5列目(工数)が「0」のとき該当する行の高さを「0」にする。 For i = ActiveSheet.UsedRange.Rows.Count To 1 Step -1 If Cells(i, 5).Value = "0" And Cells(i, 7).Value = "0" Then Rows(i).RowHeight = 0 End If Next '「E8:E55」の範囲を四捨五入する。 For i = ActiveSheet.UsedRange.Rows.Count To 1 Step -1 Range("E8:E55") = Application.Round(Range("E8:E55"), 0) '工数を四捨五入 Next 'C列の中に含まれる「小計」を検索しそこから6列目が「0」だったら行の高さを「0」にする。 Dim Rng As Range Const Retu = "C" For Each Rng In Range(Retu & "1", Range(Retu & "100").End(xlUp)) If Trim(Rng.Value) = "小   計" And _ Rng.Offset(, 6) = 0 Then Rng.EntireRow.Hidden = True End If Next Rng End Sub

専門家に質問してみよう