VBA FindメソッドとMatch関数の使い方

このQ&Aのポイント
  • VBAのFindメソッドとMatch関数を使っているコードの処理について質問です。
  • 現在、For Nextで処理していた部分をFindメソッドとMatch関数を使って書き直そうとしていますが、うまく処理されません。
  • どこが間違っているのか教えていただきたいです。
回答を見る
  • ベストアンサー

VBA FindメソッドとMatch関数のところ

まだVBAに慣れていませんが、下記のソースを書いてみました。 ★印の間の部分の処理を、最初はFor Nextで書いていたのですが、理由が解らないですが…うまく処理されない為、タイトルの2種類(セルのFindメソッドとMatch関数)を使って処理しようと思い書き直したのですがうまく処理されません。 どこがいけないのか解らず数時間も悩んでしまいました。 すみませんが、どなたか教えてください。よろしくお願いします。 Sub 外注別案内書作成() Dim ws As Worksheet 'オブジェクト格納 Dim i As Long, j As Long '繰り返す回数格納 Dim annaicode As Variant '案内場所C格納 Dim addwsname As Variant 'シート名前格納(※案内場所名) Dim flag As Boolean '真偽 Dim r As Range 'Findメソッドの返り値格納 Dim K As Long 'Match関数の返り値格納 'レポート元でQ列の情報が入っている時に、案内場所別で情報を作成する。 'レポート元でQ列に値がある時に、annaicode変数へ格納。 For i = 2 To Worksheets("レポート元").Cells(Rows.Count, "A").End(xlUp).Row If Cells(i, "Q").Value <> "" Then annaicode = Cells(i, "Q").Value End If ★ココから-------- '外注一覧でannai変数と一致した時に、addwsname変数へ格納。 FindメソッドとMatch関数 With Worksheets("外注一覧").Columns("1:1") Set r = .Find(What:=annaicode, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns) If r Is Nothing Then MsgBox i & "行目の案内場所Cの入力が不正です。" & vbCrLf & "処理を中断しますね", _ vbOKOnly + vbExclamation, "お知らせ" Else With Worksheets("外注一覧") K = .Match(annaicode, .Range(.Cells(1, "A").Value, .Cells(.Rows.Count, "A").Value), 0) addwsname = .Cells(K, "B").Value + "_案内" End With End If End With ★ココまで-------- 'ワークシートコレクション内でaddwsname変数と一致した時に、flag変数をTrueにする。 For Each ws In Worksheets If ws.Name = addwsname Then flag = True End If Next ws 'flag変数の値により、各々処理をする。 If flag = True Then Worksheets("レポート元").Cells(i, "A").EntireRow.Copy _ Destination:=Worksheets(addwsname).Cells(Rows.Count, "A").End(xlUp).Offset(1, 0) flag = False Else Worksheets.Add ActiveSheet.Name = addwsname Worksheets("レポート元").Cells(i, "A").EntireRow.Copy _ Destination:=Worksheets(addwsname).Cells(Rows.Count, "A").End(xlUp).Offset(1, 0) End If Next i End Sub

  • msnok
  • お礼率18% (5/27)

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

  • ベストアンサー
回答No.3

#1です。With Worksheets("外注一覧").Columns("1:1")については 見逃してました。Columns("A")の他にColumns(1)としても同じです。 Worksheet と WorksheetFunction は単に名前が違う別のものと考えて下さい。 これが違えば.(ドット)以降に書けるメソッドやプロパティも違ってきます。ここら辺を きっちりと認識しておかないと思わぬ間違いをする元です。 ちなみに、WorksheetFunction はワークシートの関数をVBAで使用する場合の仕掛けです。 Application.Matchも同じ結果を返しますが、検索値がなかった場合の処理が若干異なる ので注意が必要です。 使用例については以下Urlを参照して下さい。

参考URL:
http://park7.wakwak.com/~efc21/cgi-bin/exqalounge.cgi?print+201005/10050009.txt
msnok
質問者

お礼

補足にお礼を書いてしまいました。 また質問した際はよろしくお願いいたします。

msnok
質問者

補足

お返事ありがとうございます。そして連絡遅くなりすみません。 解りやすい解説とURLまでありがとごうざいます。 とても参考になりました。

その他の回答 (2)

  • mu2011
  • ベストアンサー率38% (1910/4994)
回答No.2

>With Worksheets("外注一覧").Columns("1:1")  ⇒Columnsは列番号なので、Columns("1:1")はあり得ない。   ひょっとしてA列の間違いでは、Columns("A") >K = .Match(annaicode, .Range(.Cells(1, "A").Value, .Cells(.Rows.Count, "A").Value), 0)  ⇒Matchはワークシート関数なのでこの使い方はあり得ない。   次の様なコードになります。   K = Application.Match(annaicode, .Range(.Cells(1, "A"), .Cells(.Rows.Count, "A")), 0) この二つは同じ事をしているのだから後述のMatchは不要と思う。 With Worksheets("外注一覧").Columns("A") Set r = .Find(What:=annaicode, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns) If r Is Nothing Then MsgBox i & "行目の案内場所Cの入力が不正です。" & vbCrLf & "処理を中断しますね", _ vbOKOnly + vbExclamation, "お知らせ" Else addwsname = r.Offset(0,1) + "_案内" End If End With

msnok
質問者

お礼

いつもアドバイスありがとうございます。 身近に相談できる方がいないので、とても助かります。 補足で別の質問をしてしまったのですが、 タイトルと内容が違う為、一度この質問は終了してから新たに質問をしようと思います。 ベストアンサーは悩みましたが、すみませんが、No.1の方へつけようと思います。 ありがとうございました。 そしてまたよろしくお願いいたします。

msnok
質問者

補足

お返事ありがとうございます。毎回連絡が遅くなってすみません。 >ひょっとしてA列の間違いでは、Columns("A") そこでしたか…思わぬ間違えでした^^; >K = Application.Match(annaicode, .Range(.Cells(1, "A"), .Cells(.Rows.Count, "A")), 0) なるほど、No.1の方とは頭出しが違いますが、そういう書き方もあるのですね。 今度調べてみます。 >この二つは同じ事をしているのだから後述のMatchは不要と思う。 解りました。アドバイスいただいた通りに書き直してみました。 あと少しおかしい部分も直したのですが、思うように処理出来なかったです。 ★1は毎回ワークシートをセレクトしていますが、このやり方でよいのでしょうか? ★2で、空白ではない場合として処理をしているのですが、最終的に Q列空白セル行とQ列(外注一覧にはない値)間違った値セル行を処理してしまいます。 どこが問題なのでしょうか? 次々と失敗ばかりで、すみませんがアドバイスよろしくお願いいたします。 Sub 外注別案内書作成() Dim ws As Worksheet 'オブジェクト格納 Dim i As Long, j As Long '繰り返す回数格納 Dim annaicode As Variant '案内場所C格納 Dim addwsname As Variant 'シート名前格納(※案内場所名) Dim flag As Boolean '真偽 Dim r As Range 'Findメソッドの返り値格納 'レポート元でQ列の情報が入っている時に、案内場所別で情報を作成する。 'レポート元でQ列に値がある時に、annaicode変数へ格納。 For i = 2 To Worksheets("レポート元").Cells(Rows.Count, "A").End(xlUp).Row Worksheets("レポート元").Select  ★ココ1 annaicode = "" MsgBox i If Cells(i, "Q").Value <> "" Then  ★ココ2 annaicode = Cells(i, "Q").Value End If '外注一覧でannai変数と一致した時に、addwsname変数へ格納。 Findメソッド With Worksheets("外注一覧").Columns("A") Set r = .Find(What:=annaicode, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns) If r Is Nothing Then MsgBox j - 1 & "行目の案内場所Cの入力が不正です。" & vbCrLf & "処理を中断しますね", _ vbOKOnly + vbExclamation, "お知らせ" Else addwsname = r.Offset(0, 1) + "_案内" End If End With 'ワークシートオブジェクト内でaddwsname変数と一致した時に、flag変数をTrueにする。 For Each ws In Worksheets If ws.Name = addwsname Then flag = True End If Next ws 'flag変数の値により、各々処理をする。 If flag = True Then Worksheets("レポート元").Cells(i, "A").EntireRow.Copy _ Destination:=Worksheets(addwsname).Cells(Rows.Count, "A").End(xlUp).Offset(1, 0) flag = False Else Worksheets.Add ActiveSheet.Name = addwsname Worksheets("レポート元").Rows(1).EntireRow.Copy _ Destination:=Worksheets(addwsname).Rows(1) Worksheets("レポート元").Cells(i, "A").EntireRow.Copy _ Destination:=Worksheets(addwsname).Cells(Rows.Count, "A").End(xlUp).Offset(1, 0) End If Next i End Sub

回答No.1

取りあえずMatchメソッドはWorksheetオブジェクトのメソッドではありません。 WorksheetFunctionオブジェクトのメソッドです。 よって、 >With Worksheets("外注一覧") >K = .Match(annaicode, .Range(.Cells(1, "A").Value, .Cells(.Rows.Count, "A").Value), 0) は間違いで、WorksheetFunction.Match( ... と記述する必要があります。 また、Findメソッドが成功した時にMatchを実行していますが、せっかくFindメソッドが 成功しているのにその結果を使用しないのはもったいないです。 >With Worksheets("外注一覧") >K = .Match(annaicode, .Range(.Cells(1, "A").Value, .Cells(.Rows.Count, "A").Value), 0) の代わりに K = r.Row を使用します。 ようするにFindとMatchの両方を使用する必要はありません。 当然、Matchのみを使用しても目的は果たせるはず。その場合は検索できなかった場合 どうするかを考える必要があります。 以上

msnok
質問者

補足

お返事ありがとうございます。連絡遅くなりすみません。 >取りあえずMatchメソッドはWorksheetオブジェクトのメソッドではありません。 >WorksheetFunctionオブジェクトのメソッドです。 違いがいまいち解らないですが……FunctionがつくのはWorksheetの返り値を他で使うからってことですか? >With Worksheets("外注一覧") >K = .Match(annaicode, .Range(.Cells(1, "A").Value, .Cells(.Rows.Count, "A").Value), 0) >の代わりに K = r.Row を使用します。 なるほど、そういう使い方があったのですね。 その変数Kを Cell(K, "B") として使えば、B列のK行目を取得出来そうですね。 >当然、Matchのみを使用しても目的は果たせるはず。その場合は検索できなかった場合 >どうするかを考える必要があります。 もしMatchで処理をしようとした場合、On Error Resume Next On Error GoTo 0 を使えばよいのでしょうか? 最後に、アドバイスいただいたK = r.Rowで試しにやってみたのですが、 > With Worksheets("外注一覧").Columns("1:1") 実行時エラー1004 アプリケーション定義またはオブジェクト定義のエラーです。と出てしまいました。 書き方が間違っているのでしょうか? よろしくお願いします。

関連するQ&A

  • VBA 下記ソースについて質問です。

    前回質問と同じソースなのですが、質問内容が違う為、新たに質問させていただきました。 ★1 毎回繰り返し処理をする時に、ワークシートをセレクトしていますが、このやり方でよいのでしょうか?良い方法がありましたら教えてください。 ★2 この繰り返しで、空白ではない場合に変数へ値を入れて処理をしているのですが、何故か新しいシート( _案内)を作成して、空白の部分も抜き取って処理してしまいます。 この場合は、空白の時に処理しない(GoTo でNext iの前に行くなど) の指示を書きこまないといけないのでしょうか? ☆ まだソース書いていませんが、Q列処理後でQ列と同様にS列にも案内場所C(コード)が書かれた時に同じ処理をして、S列i行目がシート名と同じ場所の時に、Q・R列i行を削除して左方向へシフトしたいのですが、 この手順は flag=Trueの部分にQ・R列i行を削除、左方向へシフト の指示を書けば良いのでしょうか? 次々と失敗ばかりで……質問長くなりすみませんが、アドバイスよろしくお願いいたします。 Sub 外注別案内書作成() Dim ws As Worksheet 'オブジェクト格納 Dim i As Long, j As Long '繰り返す回数格納 Dim annaicode As Variant '案内場所C格納 Dim addwsname As Variant 'シート名前格納(※案内場所名) Dim flag As Boolean '真偽 Dim r As Range 'Findメソッドの返り値格納 'レポート元でQ列の情報が入っている時に、案内場所別で情報を作成する。 'レポート元でQ列に値がある時に、annaicode変数へ格納。 For i = 2 To Worksheets("レポート元").Cells(Rows.Count, "A").End(xlUp).Row Worksheets("レポート元").Select annaicode = "" If Cells(i, "Q").Value <> "" Then annaicode = Cells(i, "Q").Value End If '外注一覧でannai変数と一致した時に、addwsname変数へ格納。 Findメソッド With Worksheets("外注一覧").Columns("A") Set r = .Find(What:=annaicode, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns) If r Is Nothing Then MsgBox i & "行目の案内場所Cの入力が不正です。" & vbCrLf & "処理を中断しますね", _ vbOKOnly + vbExclamation, "お知らせ" Exit Sub Else addwsname = r.Offset(0, 1) + "_案内" End If End With 'ワークシートオブジェクト内でaddwsname変数と一致した時に、flag変数をTrueにする。 For Each ws In Worksheets If ws.Name = addwsname Then flag = True End If Next ws 'flag変数の値により、各々処理をする。 If flag = True Then Worksheets("レポート元").Cells(i, "A").EntireRow.Copy _ Destination:=Worksheets(addwsname).Cells(Rows.Count, "A").End(xlUp).Offset(1, 0) flag = False Else Worksheets.Add ActiveSheet.Name = addwsname Worksheets("レポート元").Rows(1).EntireRow.Copy _ Destination:=Worksheets(addwsname).Rows(1) Worksheets("レポート元").Cells(i, "A").EntireRow.Copy _ Destination:=Worksheets(addwsname).Cells(Rows.Count, "A").End(xlUp).Offset(1, 0) End If Next i End Sub

  • エラー Nextに対するForがありませんについて

    VBAに慣れていないのですが、下記のマクロを組んでみました。 実行すると、コンパイルエラー Nextに対するForがありませんと出てしまいました。 原因が良く解らないので解る方いらっしゃいましたら教えてください。 それと、もっと良い書き方などありましたらアドバイスを下さい。 よろしくお願いします。 Sub レポート作成2each() Dim ReportMaxRow As Long '上方向に最終行を検索し行番号を格納 Dim AddWsName As String 'シート名格納 Dim Ws As Worksheet 'オブジェクト格納 Dim i As Long '繰り返しのカウントを格納 Dim flag As Boolean '真偽 ReportMaxRow = Worksheets("レポート元").Cells(Rows.Count, 1).End(xlUp).Row For i = 2 To ReportMaxRow If Cells(i, "N").Value <> "" Then If Cells(i, "O").Value <> "" Then AddWsName = Cells(i, "K").Value For Each Ws In Worksheets If Ws = AddWsName Then flag = True Next Ws   ←ここでエラーになります。 If flag = True Then Worksheets("レポート元").Cells(i, 1).EntireRow.Copy _ Destination:=Worksheets(AddWsName).Cells(Rows.Count, 1).End(xlUp).Offset(1, 0) Else Worksheets.Add ActiveWorksheet.Name = AddWsName Worksheets("レポート元").Cells(i, 1).EntireRow.Copy _ Destination:=Worksheets(AddWsName).Cells(Rows.Count, 1).End(xlUp).Offset(1, 0) End If MsgBox i + "行目の発注数の入力がませんでした。" & vbNewLine & "処理を中断します, _ vbOKOnly + vbExclamation, "お知らせ" End If Else MsgBox i + "行目の発注数の入力がませんでした。" & vbNewLine & "処理を中断します", _ vbOKOnly + vbExclamation, "お知らせ" End If Next i End Sub

  • If Like Then条件式可変の場合の処理

    VBAにてSheet1の指定された番地にあるセルの値がSheet2のセル範囲にない場合はセルに色をつけると言うマクロを組んでいます。 Sub test() Dim i,z As Integer Dim WS As Worksheet Dim LastRow As Integer Dim Word1,Word2,Word3 As String Set WS = Worksheets("Sheet1") Word1 = WS.Cells(1,16).Value Word2 = WS.Cells(1,17).Value Word3 = WS.Cells(1,18).Value with Worksheets("Sheet2") LastRow = .Range("A" & Rows.Count).End(xlUp).Row For i = 3 To LastRow For z = 6 To 9 If .Cells(i,z).Value Like "*" & Word1 & "*" Or _ .Cells(i,z).Value Like "*" & Word2 & "*" Or _ .Cells(i,z).Value Like "*" & Word3 & "*" Then Else .Cells(i,z).Interior.ColorIndex = 6 End If Next Next End Sub 上記のマクロで変数Word1,2,3が1つだけの場合もあれば Word10まである場合も有り式を変更する必要が有ります。。 この場合、If Like 変数 Or の部分をフレキシブルに対応させる為にはどの様な式を書けば良いでしょうか(ToT)? 申し訳ありませんがご教授下さい(ToT) 宜しくお願い致します。

  • VBA どこでもセル選択

    教えて頂いたVBAなのですがもう一つ Sub Macro1() Dim Ws01 As Worksheet Dim Counter As Long, i As Long, j As Long Dim INP As String Set wS = Worksheets("Sheet4") wS.Cells.ClearContents For i = 3 To ActiveSheet.UsedRange.Rows.Count INP = "" For j = Selection(1).Column To Selection(Selection.Count).Column If Cells(i, j) = 1 Then INP = INP & Cells(2, j) & "," End If Next j Counter = Counter + 1 If INP <> "" Then wS.Cells(Counter, "A") = Left(INP, Len(INP) - 1) End If Next i End Sub -------------------------------------------------------------- For i = 3 のところを3としないでどのセル(行)にも対応させたいのですが どうすればいいでしょうか?

  • Excel VBA; 複数のループ処理

    ↓のようなコードがあります。 Dim i As Long, MaxRow1 As Long, MaxRow2 As Long MaxRow1 = Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row MaxRow2 = Worksheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Row For i = 1 To MaxRow1 Worksheets("Sheet1").Cells(i, 1).Value = i . Next i For i = 1 To MaxRow2 Worksheets("Sheet2").Cells(i, 1).Value = i . Next i これらを最大行の多いシートに合わせて、パフォーマンスを良くしたいと思います。 同様の処理をシート1、シート2で実施しているので纏めて記述したいです。 シート1、シート2に対する処理をサブルーチンにする方法しかありませんか? どなたかお願いします。 If MaxRow1 >= MaxRow2 Then For i = 1 To MaxRow1 Else For i = 1 To MaxRow2 End If Worksheets("Sheet1").Cells(i, 1).Value = i Worksheets("Sheet2").Cells(i, 1).Value = i . Next i

  • Excel VBA 連番印刷

    昨日以下の質問をさせていただいた者です。 http://okwave.jp/qa/q8349562.html こちらで教えていただいた以下のコードに、 J2のセルに連番を振るコードを付け足したいと思い、 同じくこちらのサイトの過去の履歴にあった以下コードを参考にとやってみているのですが、 Next で指定された変数の参照が無効です。と言われてしまいます… 印刷部数の指定はいらず、sheet印刷のJ2セルに1から始まる連番を振りたいのです。 どのように修正をしたらいいのかご教示願います。 Sub Sample4() Dim i As Long, endRow1 As Long, endRow2 As Long, myArea1 As Range, myArea2 As Range Dim wS1 As Worksheet, wS2 As Worksheet, wS3 As Worksheet Set wS1 = Worksheets("DB") Set wS2 = Worksheets("印刷") Set wS3 = Worksheets("Sheet3") endRow1 = wS1.Cells(Rows.Count, "A").End(xlUp).Row Range(wS1.Cells(1, "A"), wS1.Cells(endRow1, "A")).AdvancedFilter Action:=xlFilterInPlace, unique:=True wS1.Range("A:A").Copy wS3.Range("A1") wS1.ShowAllData For i = 2 To wS3.Cells(Rows.Count, "A").End(xlUp).Row endRow2 = wS2.Cells(Rows.Count, "B").End(xlUp).Row If endRow2 > 9 Then Range(wS2.Cells(10, "B"), wS2.Cells(endRow2, "H")).ClearContents Range(wS2.Cells(10, "J"), wS2.Cells(endRow2, "J")).ClearContents End If wS1.Range("A1").AutoFilter field:=1, Criteria1:=wS3.Cells(i, "A") wS2.Range("B6") = wS3.Cells(i, "A") Set myArea1 = Range(wS1.Cells(2, "B"), wS1.Cells(endRow1, "H")).SpecialCells(xlCellTypeVisible) Set myArea2 = Range(wS1.Cells(2, "I"), wS1.Cells(endRow1, "I")).SpecialCells(xlCellTypeVisible) myArea1.Copy wS2.Activate ActiveSheet.Range("B10").Select Selection.PasteSpecial Paste:=xlPasteValues myArea2.Copy wS2.Activate ActiveSheet.Range("J10").Select Selection.PasteSpecial Paste:=xlPasteValues endRow2 = wS2.Cells(Rows.Count, "B").End(xlUp).Row 'Range(wS2.Cells(1, "A"), wS2.Cells(endRow2, "J")).PrintOut Next i wS1.AutoFilterMode = False wS3.Cells.Clear End Sub 連番印刷のコード Sub NumberPrint() Dim idx As Integer Dim res  res = Application.InputBox("印刷部数を入力してください", Type:=1)  If res > 0 Then   For idx = 1 To res    Range("AW3").Value = idx    ActiveSheet.PrintOut   Next idx  End If End Sub

  • VBA 請求データ一覧からの複数の処理

    先週 kkkkkmさんに質問をさせて頂きまして、 いろいろご指導を頂いたものです。 続編の様な形になってしまいますが、 抽出するデータの環境設定を変更致しました。 ご質問させて頂く内容は前回とほとんど変更がないのですが、 あらためて下記に記載させて頂きます。 <Worksheet1のデータ> J列~AM列までが課税金額 「J,K,L」「M,N,O」・・・「AK,AL,AM」と3列1組(コード・費目・金額) 1組の行もあれば、複数組の行もあり。 AN列~BB列までが非課税金額 課税金額と同じく3列1組 1組の行もあれば、複数組の行もあり。 「BC」=消費税、「BD」=合計金額 ※AN列の前に不規則な空白セルあり   BC列の前に不規則な空白セルあり 文章で上手く説明出来ているか自信がありませんので、 エクスポートした元データ Worksheet1と、 vbaを用いて作成した Worksheet3 をご参考に添付致します。 Worksheet1の2行目がWorksheet3の2行目に対応しています。 3行目、4行目も同様です。 不規則な空白が原因でしょうか・・・。 M列、O列は問題ないのですが、 金額が合わなかったり、N列に金額を引いてこないのです。 実行しているコードは下記になります。 Dim i As Long, j As Long, k As Long Dim Ws1 As Worksheet, Ws2 As Worksheet, Ws3 As Worksheet Dim mTotal(4) As Long Dim LastRow As Long Dim List(4) As Variant Set Ws1 = Sheets("Sheet1") Set Ws2 = Sheets("Sheet2") Set Ws3 = Sheets("請求書ひな形") List(1) = Ws2.Range(Ws2.Cells(1, "A"), Ws2.Cells(Rows.Count, "A").End(xlUp)).Value List(2) = Ws2.Range(Ws2.Cells(1, "B"), Ws2.Cells(Rows.Count, "B").End(xlUp)).Value List(3) = Ws2.Range(Ws2.Cells(1, "C"), Ws2.Cells(Rows.Count, "C").End(xlUp)).Value List(4) = Ws2.Range(Ws2.Cells(1, "D"), Ws2.Cells(Rows.Count, "D").End(xlUp)).Value LastRow = UBound(List(1)) For i = 2 To 4 If LastRow < UBound(List(i)) Then LastRow = UBound(List(i)) End If Next For i = 2 To Ws1.Cells(Rows.Count, "J").End(xlUp).Row mTotal(1) = 0 mTotal(2) = 0 mTotal(3) = 0 mTotal(4) = 0 For j = Columns("J").Column To Columns("BB").Column Step 3 For k = 2 To LastRow If UBound(List(1)) >= k Then If Ws1.Cells(i, j).Value = List(1)(k, 1) Then mTotal(1) = mTotal(1) + Ws1.Cells(i, j).Offset(0, 2).Value Exit For End If End If If UBound(List(2)) >= k Then If Ws1.Cells(i, j).Value = List(2)(k, 1) Then mTotal(2) = mTotal(2) + Ws1.Cells(i, j).Offset(0, 2).Value Exit For End If End If If UBound(List(3)) >= k Then If Ws1.Cells(i, j).Value = List(3)(k, 1) Then mTotal(3) = mTotal(3) + Ws1.Cells(i, j).Offset(0, 2).Value Exit For End If End If If UBound(List(4)) >= k Then If Ws1.Cells(i, j).Value = List(4)(k, 1) Then mTotal(4) = mTotal(4) + Ws1.Cells(i, j).Offset(0, 2).Value Exit For End If End If Next Next Ws3.Cells(i, "J").Value = mTotal(1) Ws3.Cells(i, "K").Value = mTotal(2) Ws3.Cells(i, "L").Value = mTotal(3) Ws3.Cells(i, "N").Value = mTotal(4) Ws3.Cells(i, "M").Value = Ws1.Cells(i, "BC").Value Ws3.Cells(i, "O").Value = Ws1.Cells(i, "BD").Value Next Set Ws1 = Nothing Set Ws2 = Nothing Set Ws3 = Nothing End Sub 本当に何度も申し訳ございません。 お時間がある時に見て頂けると有り難いです。 どうぞ宜しくお願い致します。

  • エクセル VBA

    VBA内で、そのVBAの実行を制御することは可能でしょうか? 下のようなコードを作ったのですが、 Sub 承認書作成() Dim ws0 As Worksheet, ws1 As Worksheet, r1 As Range Dim i As Long Dim nyuryoku(), chikuseki() Set ws0 = Worksheets("承認書作成") Set ws1 = Worksheets("顧客データ") Set ws2 = Worksheets("業者コード") Set ws3 = Worksheets("承認通知書") Worksheets("顧客データ").Select Range("テーブル1[[#Headers],[NO.]]").Select Selection.End(xlToRight).Select Selection.End(xlDown).Select Selection.ListObject.ListRows.Add AlwaysInsert:=False Range("B7").Select nyuryoku = Array("b5", "d5", "f5", "h5", "j5", "l5", "n5", "p5", "b6", "d6", "f6", "h6", "j6", "l6", "n6", "p6", "b4", "d4") '転記したいセルの位置 chikuseki = Array("0", "1", "5", "6", "8", "9", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "53", "54") '転記先の列のオフセット値  Set r1 = ws1.Range("f" & Rows.Count).End(xlUp).Offset(0) 'データ蓄積セル  For i = 0 To UBound(nyuryoku) r1.Offset(0, chikuseki(i)).Value = ws0.Range(nyuryokui)).Value '入力 Next MsgBox "入力完了" Dim lRowNum As Long '転記先となる行番号を求める lRowNum = ws1.Cells(Rows.Count, "b").End(xlUp).Row '転記 ws3.Cells(6, "d").Value = ws1.Cells(lRowNum, "j").Value ws3.Cells(17, "g").Value = ws1.Cells(lRowNum, "c").Value ws3.Cells(22, "g").Value = ws1.Cells(lRowNum, "l").Value ws3.Cells(22, "ac").Value = ws1.Cells(lRowNum, "ab").Value    Set ws0 = Nothing   Set ws1 = Nothing End Sub ここに、     If call Macro1 then call 承認書作成  '上のマクロです    Else: Msgbox"中止" 「Macro1を実行しないと承認書作成マクロを実行できない」 という コードを組み込みたいのですが、うまくいきません。 VBA内に同じVBAを組み込むことは不可能なのでしょうか?

  • 【至急助けて下さい!!】VBAでのIF関数挿入

    VBA初心者です。上級者の方助けてください。 VBAで入力セルを消去後、IF関数をN列に挿入したいです。 挿入したいIF関数のところが解決できればあとの記述はなんとかなります。 ■挿入したいIF関数 =IF(M4=$Y$5,$Z$9,IF(M4=$Y$6,$Z$9,IF(M4=$Y$7,$Z$9,IF(M4=$Y$8,$Z$6,IF(M4=$Y$9,$Z$10,IF(M4=$Y$10,$Z$9,IF(M4=$Y$14,$Z$7,IF(M4=$Y$15,$Z$8,"")))))))) 他関数は下記構文でうまくいくのですが、 IF関数はどのように記述したらよろしいでしょうか。 ■他 ws.Cells(i, jig_col).Value = "=VLOOKUP(F" & i & ",Sheet1!$A$2:$C$358,2,0)" ■現在の記述 Dim ws As Worksheet Dim endrow As Long Dim endcol As Long Dim you_col As Integer Dim gak_col As Integer Dim jig_col As Integer Dim bc_col As Integer Dim chg_col As Integer Dim i As Long '確認メッセージを表示し、「NO」の場合は処理を行わない If MsgBox("入力されている内容をクリアします。よろしいですか?", vbYesNo) = vbNo Then Exit Sub End If '画面の更新を行わない Application.ScreenUpdating = False Set ws = ThisWorkbook.Sheets("シンフォームイレギュラー運用状況") '呼び出し元シートの最終行、最終列を取得する endrow = ws.Cells(ws.Rows.Count, 6).End(xlUp).Row endcol = ws.Cells.Find(What:="変更フラグ", LookIn:=xlValues, LookAt:=xlWhole).Column - 2 If endrow < 4 Then Exit Sub ws.Range(ws.Cells(4, 1), ws.Cells(endrow, endcol)).ClearContents you_col = ws.Cells.Find(What:="曜日", LookIn:=xlValues, LookAt:=xlWhole).Column gak_col = ws.Cells.Find(What:="学年", LookIn:=xlValues, LookAt:=xlWhole).Column jig_col = ws.Cells.Find(What:="事業所", LookIn:=xlValues, LookAt:=xlWhole).Column 'bc_col = endcol - 1 'chg_col = endcol For i = 4 To endrow ws.Cells(i, you_col).Value = "=B" & i ws.Cells(i, gak_col).Value = "=VLOOKUP(F" & i & ",Sheet1!$A$2:$C$358,3,0)" ws.Cells(i, jig_col).Value = "=VLOOKUP(F" & i & ",Sheet1!$A$2:$C$358,2,0)" 'ws.Cells(i, bc_col).Value = "=IFERROR(MID(H" & i & ",LEN(H" & i & ")-1,1), "")" 'ws.Cells(i, chg_col).Value = 0 ws.Range("W" & i).Value = 0 Next '画面の更新を行う Application.ScreenUpdating = True End Sub

  • VBA 高速化

    以下のコードを改良して早く処理できるようにしたいです。素因数分解をして、素因数の数を数えるプログラムです。 Sub 素因数を数える() Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Dim I As Long, j As Long, cnt As Long, wS As Worksheet, k As Long, Set wS = Worksheets("Sheet2") k = Worksheets("Sheet1").Range("A100010").End(xlUp).Row - 1 For dd = 3 To k Call aaa(Range("A" & dd)) Next dd Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic End Sub Private Sub aaa(ByVal Target As Range) Set wS = Worksheets("Sheet2") If Intersect(Target, Range("A:A")) Is Nothing Or Target.Count > 1 Then Exit Sub With Target If Not IsNumeric(.Value) Then Exit Sub If .Value Mod 1 = 0 Then Range("D1") = .Value For I = 1 To wS.Cells(Rows.Count, "A").End(xlUp).Row Do While Cells(Rows.Count, "D").End(xlUp) Mod wS.Cells(I, 1) = 0 cnt = cnt + 1 Cells(Rows.Count, "D").End(xlUp).Offset(1) = Cells(Rows.Count, "D").End(xlUp) / wS.Cells(I, 1) Loop If Cells(Rows.Count, "D").End(xlUp) = 1 Then Exit For Next I End If .Offset(, 1) = cnt End With Range("D:D").Clear End Sub 以前教えていただいたコードを使って書きました。 どういう状況で使っているかといいますと、シート1のA列に自然数を2から順番に並べ、シート2のA列に素数を並べておき、プログラムを実行すると、B列に素数の数が表示されるという具合です。 大変役に立っていたのですが、10萬ほどのデータを扱おうとすると、自分のコンピュータでは時間がかかりすぎます。そこでコードを改良して高速化をしたいのです。 いま考えられる改良点は、 1、D列を使って行っている処理をメモリで行うようにして、セルへのアクセスを省けないか 2、aaaの5行目の、"wS.Cells(Rows.Count, "A").End(xlUp).Row"この処理を簡単な変数の処理で代用できないか ということです。他にも高速化できる方法があれば教えてください。 よろしくお願いします。

専門家に質問してみよう