VBAのCodeModule.Linesの記入方法

このQ&Aのポイント
  • VBAのCodeModule.Linesを使用して特定の条件に一致する行を置き換える方法がわかりません。
  • 文字列を検索し、数値の合計が一定値以上かつ特定の条件に一致する行を置き換える処理を行いたい場合、VBAのCodeModule.Linesを使用します。
  • しかし、記述する際にどの箇所にダブルクォーテーションを付けるべきかが分からず、試行錯誤しています。具体的な記述方法を教えていただけませんか?
回答を見る
  • ベストアンサー

VBAのCodeModule.Linesの記入方法

Set Target = ThisWorkbook With Target.VBProject.VBComponents("Module2").CodeModule For i = 1 To .CountOfLines If .Lines(i, 2) = Range("AE77").FormulaArray = _ "=SUMPRODUCT((ISNUMBER(FIND(""1号施設"",R11C19:R72C19)))*1,((IF(ISNUMBER(範囲1),範囲1,0)+IF(ISNUMBER(範囲2),範囲2,0)+IF(ISNUMBER(範囲3),範囲3,0)+IF(ISNUMBER(範囲4),範囲4,0)+IF(ISNUMBER(範囲5),範囲5,0)+IF(ISNUMBER(範囲6),範囲6,0))>=8)*1)" Then .ReplaceLine i, Range("AE77").FormulaR1C1 = _ "=ROUNDDOWN((SUMIF(R11C19:R72C19,""*1号施設*"",範囲1)+SUMIF(R11C19:R72C19,""*1号施設*"",範囲2)+SUMIF(R11C19:R72C19,""*1号施設*"",範囲3)+SUMIF(R11C19:R72C19,""*1号施設*"",範囲4)+SUMIF(R11C19:R72C19,""*1号施設*"",範囲5)+SUMIF(R11C19:R72C19,""*1号施設*"",範囲6))/8,0)" End If Next i End With の If .Lines(i, 2) =     以下の Range("AE77").FormulaArray = _ "=SUMPRODUCT((ISNUMBER(FIND(""1号施設"",R11C19:R72C19)))*1,((IF(ISNUMBER(範囲1),範囲1,0)+IF(ISNUMBER(範囲2),範囲2,0)+IF(ISNUMBER(範囲3),範囲3,0)+IF(ISNUMBER(範囲4),範囲4,0)+IF(ISNUMBER(範囲5),範囲5,0)+IF(ISNUMBER(範囲6),範囲6,0))>=8)*1)"  Then 記入方法が解りません。 605行目からは2行にわたるコードを記載してるのですが、Range("AE77").FormulaArray = 以下>=8)*1)"まで(605行以外にもあるのでForで廻してます) 文字列として””で括るるんだろうなと思ってトライしましたが、””で括る場所が多すぎてどこに付ければいいのやらです。最初と最後を””付けるだけでなく元々("AE77")のようになっている場所には更に””を付けたりするのでしょうか?それも試しましたが、途中の:にも何かしなくてはならないような‥ どなたかご教示願います。

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

  • ベストアンサー
  • end-u
  • ベストアンサー率79% (496/625)
回答No.1

Dim s As String s = " Range(""AE77"").FormulaArray = _" & vbCrLf & _ " ""=SUMPRODUCT((ISNUMBER(FIND(""""1号施設"""",R11C19:R72C19)))*1,(" & _ "(IF(ISNUMBER(範囲1),範囲1,0)+IF(ISNUMBER(範囲2),範囲2,0)" & _ "+IF(ISNUMBER(範囲3),範囲3,0)+IF(ISNUMBER(範囲4),範囲4,0)" & _ "+IF(ISNUMBER(範囲5),範囲5,0)+IF(ISNUMBER(範囲6),範囲6,0))>=8)*1)""" MsgBox s s = " Range(""AE77"").FormulaR1C1 = _" & vbCrLf & _ " ""=ROUNDDOWN((SUMIF(R11C19:R72C19,""""*1号施設*"""",範囲1)" & _ "+SUMIF(R11C19:R72C19,""""*1号施設*"""",範囲2)" & _ "+SUMIF(R11C19:R72C19,""""*1号施設*"""",範囲3)" & _ "+SUMIF(R11C19:R72C19,""""*1号施設*"""",範囲4)" & _ "+SUMIF(R11C19:R72C19,""""*1号施設*"""",範囲5)" & _ "+SUMIF(R11C19:R72C19,""""*1号施設*"""",範囲6))/8,0)""" MsgBox s 『"』(ダブルクォート)文字列をコード出力したい時、 コード内に記述する時は『""』のように2つ重ねます。2つで『"』1コ分です。 数式に『"1号施設"』と記述したい時にコード内では『""1号施設""』としますよね。 コード内の『""1号施設""』を、検索対象文字列としてさらにコード内で記述するには 『""""1号施設""""』とします。 またコード内でインデントしてるでしょうから、その分のスペースも考慮した文字列にしないといけませんね。 (または各行Trimして判断するか) さらに、2行分を検索してますから " 1行目 _" & vbCrLf & " 2行目" と、vbCrLf で繋いで判定しないといけないです。 また、 .ReplaceLine i, "置換文字列1行目" & vbCrLf & "置換文字列2行目" として i 行目1行、に対して2行置換してますから、元コードの直後の行を削除する必要があります。 1行余分に挿入されてますからその分ずれて .DeleteLines i + 2 です。 しかしながら、Module内コードをマクロから書き換える操作はおすすめしません。 事情があるのでしょうけど、そもそもの仕様から見直すようにされたほうが良いでしょう。 恐らく多数のユーザーに配布してしまったBookの書き換えの為でしょうけど、 そういった配布の問題については、マクロブックとデータブックの分離、アドインの導入、 など検討されたほうが良いかと思います。 http://www.asahi-net.or.jp/~ef2o-inue/haifu/sub06_010.html

yokokama46
質問者

お礼

最新の回答で気付かされましたが、すでにこの回答時で完璧だったのですね。 ありがとうございました。

yokokama46
質問者

補足

end-uさん。お久しぶりです。1年くらい前によくここで質問していたのですが、その時も何度も助けて頂きました。今回も早速の回答ありがとうございます。 さて、試させていただいたところ。 まさにMsgBox には寸分たがわぬ式が表示されます。 そこでs =以下をIf .Lines(i, 2) =以下にそのまま貼り付けてみてテストしましたが、ヒットしません。スルーされてしまいます。 そこでそれ以前の流れの検証のため、式を簡略しIf .Lines(i, 1) ="A = B" として適当なところにA=Bと記入しヒットするか検証し、結果問題なくヒットしました。 よって同一の文字列と見ていないということになるのでしょうが、しっかり記入してるのを確認してます。 If .Lines(i, 2) =    ←  辺りに問題あるのでしょうか?(でも間違いなく2行ですし‥) お手数ですが、今一度、お付き合いねがえませんか?

その他の回答 (1)

  • end-u
  • ベストアンサー率79% (496/625)
回答No.2

>またコード内でインデントしてるでしょうから、その分のスペースも考慮した文字列にしないといけませんね。 インデントのスペースも文字列の前に付けてますか? 一応チェックコードとして Sub test()   Dim s As String   Dim i As Long   With ThisWorkbook.VBProject.VBComponents("Module2").CodeModule     For i = 1 To .CountOfLines       If Trim(.Lines(i, 1)) = "Range(""AE77"").FormulaArray = _" Then         Debug.Print .Lines(i, 2)         Debug.Print "■検索文字↓■"         Debug.Print """" & Replace(.Lines(i, 1), """", """""") & """" & " & vbCrLf & _"         Debug.Print """" & Replace(.Lines(i + 1, 1), """", """""") & """"       End If     Next   End With End Sub うまくいけば[イミディエイトウィンドウ]に検索文字が書き出されます。 それを使ってみてください。

yokokama46
質問者

お礼

>またコード内でインデントしてるでしょうから、その分のスペースも考慮した文字列にしないといけませんね。  見落としてました。まさにそこでした。 自分なりにDebug.Printしてみてたりしてたのですがスペースを考慮させてない表示でしたので、それをみてもまったく同じ式なのに‥と悩んでました。 ついでに、スペースを反映させるデバックのコードまで示して頂き大変助かります。 実は、さらに類似の処理も続くので、スペース数えたりする手間が省けました。 また、考えかたもご教示頂き、いつもながら頭が下がります。 まさに痒いところに手が届く完璧な回答でした。 助かりました。本当にありがとうございます。 end-uさんはいろんな方に回答なされているでしょうから覚えてないとは思いますがyokokama46は昔end-uさんに本当に助けて貰ったのを覚えています。 また、一年振り以上なのでここのデザインも変わったことに少しとまどいながらも、ken-kenSPさんやredfox63さんにもお世話になってたことも思い出したりしました。 関係ない話で恐縮ですが、久しぶりの質問に、一番お世話になったend-uさんからの回答でしたので、驚きと感動でしたのでお許し下さい。 また、よろしくお願いします。

関連するQ&A

  • VBAの複数条件の検索について

    お世話になります。 VBAでEvaluate("SUMPRODUCT((棚卸!$A$1:$A$300=LEFT(C" & i & ",2))*(ISNUMBER(FIND(LEFT(D$1,3),棚卸!$B$1:$B$300)))*(ISNUMBER(FIND(D$2,棚卸!$C$1:$C$300))),棚卸!$F$1:$F$300)")という構文があります。 現在困っていることは、ISNUMBER(FIND(LEFT(D$1,3)のD$1をE$1、F$1、G$1としたいのですが、どのようにすればよいか分りません。 初歩的な質問で申し訳ありませんが、ご教示のほど宜しくお願いいたします。

  • vbaの速度向上(sumif関数)

    エクセルvbaの速度を向上できないか、お知恵を貸していただきたく存じます。 以下のvba(sumif関数)をもっと速めたいです。何とかできないでしょうか。長い記載となり申し訳ないのですが、何卒よろしくお願い申し上げます。 myCnt7 = 2 Do Worksheets("●").Cells(myCnt7, 4).Value = WorksheetFunction.SumIf(Worksheets("◆").Range("B:R"), Worksheets("●").Cells(myCnt7, 3), Worksheets("◆").Range("R:R")) - WorksheetFunction.SumIf(Worksheets("★").Range("B:C"), Worksheets("●").Cells(myCnt7, 3), Worksheets("★").Range("C:C")) Worksheets("●").Cells(myCnt7, 7).Value = WorksheetFunction.SumIf(Worksheets("◆").Range("B:R"), Worksheets("●").Cells(myCnt7, 6), Worksheets("◆").Range("R:R")) - WorksheetFunction.SumIf(Worksheets("★").Range("B:C"), Worksheets("●").Cells(myCnt7, 6), Worksheets("★").Range("C:C")) Worksheets("●").Cells(myCnt7, 10).Value = WorksheetFunction.SumIf(Worksheets("◆").Range("B:R"), Worksheets("●").Cells(myCnt7, 9), Worksheets("◆").Range("R:R")) - WorksheetFunction.SumIf(Worksheets("★").Range("B:C"), Worksheets("●").Cells(myCnt7, 9), Worksheets("★").Range("C:C")) Loop While myCnt7 > 201 ※シート●のC列から3列ごとに、Sumifの検索条件があります。 ※シート●のD列から4列ごとに、Sumifの計算結果を出力させます。 ※計算対象シートは、シート◆とシート★の2つです。  シート◆のSumif合計から、シート★のSumif合計を差し引いています。  Sumifの条件自体は、どちらのシートも同じ(シート●)。 ※上記のSumif関数の記述は、3つですが、実際の記述は24あります。 ※すなわち、検索条件の組み合わせが24あり、201行分をmyCnt7でLoopさせて実行しています。

  • 文字列AかBを含むセル数をSUMPRODUCT関数で求める場合

    文字列AかBを含むセル数をSUMPRODUCT関数で求める場合 エクセル2000です。 A1:A10のセル範囲だとして =SUMPRODUCT(ISNUMBER(FIND({"A","B"},A1:A10))*1) とすると、同一セルにA、Bの両方があった場合、重複してカウントされてしまいます。 重複を除外するために、 =SUMPRODUCT(ISNUMBER(FIND({"A","B"},A1:A10))*1)-SUMPRODUCT(ISNUMBER(FIND("A",A1:A10))*ISNUMBER(FIND("B",A1:A10))) と、重複してカウントされた数から両方が存在するセルの数を減じて求めましたが、以下のようなより簡素な式でも求められことがわかりました。 =SUMPRODUCT((ISNUMBER(FIND("A",A1:A10))+ISNUMBER(FIND("B",A1:A10))>=1)*1) この式でなぜAB両方があるセルが重複カウントされないのかどうもわかりません。 ご教示いただければ幸いです。 なお、SUMPRODUCTではなく =SUM(COUNTIF(A1:A10,{"*A*","*B*"}))-SUM(COUNTIF(A1:A10,{"*A*B*","*B*A*"})) でもできることは存じておりますが、今回はSUMPRODUCTの疑問として質問いたしました。

  • Evaluateを使ってマクロに記述した関数に変数を使う方法

    Evaluateを使ってマクロに記述した関数に変数を使う方法 "=SUMPRODUCT((ISERROR(FIND(A1,B1:B100))=FALSE)*(C1:C100<=10))" という関数を普段使用しています。 ふとこの関数をマクロで実行させようと思い(理由はありません、思い付きです)、 Range("D1").Value = Evaluate("SUMPRODUCT((ISERROR(FIND(A1,B1:B100))=FALSE)*(C1:C100<=10))") としてみました。うまくいきました。 次に、 Dim i As Long For i = 1 To 5 Range("D" & i).Value = Evaluate("SUMPRODUCT((ISERROR(FIND(A1,B1:B100))=FALSE)*(C1:C100<=10))") next としてみました。ここで考えたのですが、 FIND(A1,B1:B100) この部分の「A1」を「i」を使って(つまりRange("D" & i)に連動させて)変数にすることは出来るのでしょうか? ご教示願います。 今回は単なる好奇心で普段使っている関数をマクロで表現できないかなと思った次第で、どうしても知りたい!必要だ!というわけではありません。 お暇なときにお願いします。

  • VBAにて計算式を入力したい

    VBAにてマクロ作成中です。 下記の計算式をマクロから入力したいのですが、 どのような式になりますでしょうか? =SUM(SUMIF(稼動データ!F2:F89,{"D","F"},稼動データ!I2:I89)) R1C1形式だと、下記でうまくいくのですが。。 Range("G42").FormulaR1C1 = _ "=SUM(SUMIF(稼動データ!R[-40]C[-1]:R[47]C[-1],{" & """D"",""F""" & "},稼動データ!R[-40]C[2]:R[47]C[2]))"

  • エクセルVBAのFindの不具合

    入力シートの4~2000行にデータをフォームを使って入力し、そのフォームを閉じる際に集計シートで集計する家計簿を作ってます。集計シートでは、食費・交際費などのコードがB5:B22に入っており、それぞれの合計をC5:C22に表示させたいのです。SUMIFを使えば楽なのですが、勉強のために極力VBAで処理させます。 フォームを閉じた際のソース(抜粋)は以下の通りです。 -------------------------------- Private Sub CommandButton2_Click() Dim i As Integer Dim コード As Integer Dim 金額 As Long Dim 集計行 As Integer Dim コード範囲 As Range Unload Me Set コード範囲 = Worksheets("集計").Range("b5, b22") For i = 4 To 2000 コード = Cells(i, 3).Value 金額 = Cells(i, 5).Value 集計行 = コード範囲.Find(コード).Row Next i End Sub -------------------------------- For~Nextの中はもっと処理を追加しなければならないのですが、とりあえず現段階で、   実行時エラー91(オブジェクト変数またはWithブロックが設定されていません) が   集計行 = コード範囲.Find(コード).Row の行で発生します。行番号だけを取得しようとしているので、Findの行だけを整数型変数に代入したいのですが・・・ 間違っている点をお教え下さい。 ご面倒でなければ、 Application.WorksheetFunctionに置き換える方法も教えていただければ幸いです。 よろしくお願いします。

  • VBAで教えてください。

    以前ここで教えていただいたVBAで http://jisaku.155cm.com/src/1371930716_9b9006528605642980beed48a8998013b0731e4b.jpg のようにA列のテスト4をクリックしたときにC列のテスト4が一発で解るようにしたいです。 もちろん、テスト11をクリックしたときは、テスト4塗りつぶしは解除され、 テスト11が塗りつぶされるようにしたいです。 写真は塗りつぶししていますが、解るようにしたいだけなので、塗りつぶしにはこだわっていません。 あと、E、F、G列は解りやすく並べているだけで、実際はA、B、C列だけです。 それと、C列は関数を使って表示してあります。 という質問で Private Sub Worksheet_SelectionChange(ByVal Target As Range) 'この行から Dim i As Long Range("C:C").Interior.ColorIndex = xlNone If Application.Intersect(Target, Range("A:A")) Is Nothing Or Target.Count <> 1 Then Exit Sub On Error Resume Next Application.ScreenUpdating = False ActiveSheet.Cells.interio.ColorIndex = xlNone For i = 1 To Cells(Rows.Count, 1).End(xlUp).Row If Cells(i, "C") = Target Then Cells(i, "C").Interior.ColorIndex = 3 End If Next i Application.ScreenUpdating = True End Sub 'この行まで をシートのコードに張り付ければいいですよ。と教えてくれたものがあるのですが、 A列でクリックした文字をC列からすべて見つけて反転してくれないようです。何個か反転してくれない ものが出てきてしまいました。 C列が何百行とかなってしまうと、すべての同じ文字を検索してくれないのでしょうか? ちなみに列がここに掲載しているものと違うので Private Sub Worksheet_SelectionChange(ByVal Target As Range) 'この行から Dim i As Long Range("R:R").Interior.ColorIndex = xlNone If Application.Intersect(Target, Range("B:B")) Is Nothing Or Target.Count <> 1 Then Exit Sub On Error Resume Next Application.ScreenUpdating = False ActiveSheet.Cells.interio.ColorIndex = xlNone For i = 1 To Cells(Rows.Count, 1).End(xlUp).Row If Cells(i, "R") = Target Then Cells(i, "R").Interior.ColorIndex = 3 End If Next i Application.ScreenUpdating = True End Sub 'この行まで のCをRにAをBに変更して使ってます。 これがいけないのかな? よろしくお願いします。

  • VBA 変動する総計を半期合計で計算したい。

    ピボットテーブルの総計行が元データが追加されるので変動してしまいます。 他のセルに(C37)式を入れていますが、ピボットの行が更新されるたびに 総計行の範囲を毎回張りなおさなければならない状態です。 変動しても他のセル(C37)に、合計が計算できるようにしたいです。 その総計行に対する合計の数式は以下です。(C37に入ってる式です。) =SUMIF(21:21,">=2007/10/1 ",29:29 )-SUMIF(21:21,">=2008/4/1 ",29:29 ) 29行目が総計で常に変動します。 そこで、A行に総計という文字がでたら、1つ右隣から始まる範囲での式がほしいです。 C37セルにその合計の値が表示されるようにしたいです。 21行目(固定)は日付で「2007/10/1」「2008/2/1」と2/1のように 月初の日付がB21セルから未来へ向かって表示。空白もあります。 (年度集計行を20行目に入れたため。) then以下どう書くか教えてください。 Sub 総計() Dim myRng As Range For Each myRng In Range("A:A") If myRng.Value = "総計" Then ※※※※※※※※※※ End If Next myRng End Sub

  • EXCEL関数について

    質問があります。 エクセルのA行に 定期点検 (月度検査) ラジオ修理 ボリューム つまみ 校正 視力検査 ボールペン 発注 替芯 購入 コピー用紙 経費 ポケットティッシュ配布用    ・    ・       ・  とあるのを、B行に下記の用に変換したいのですが、 検査 修理 検査 検査 購入 購入 購入 購入 その他 その他 その他    ・    ・       ・  下記のように関数をつくったのですが、うまく動きません =IF(A1="","",IF(ISNUMBER(FIND("点検",A1)),"検査",IF(ISNUMBER(FIND("修理",A1)),"修理",IF(ISNUMBER(FIND("校正",A1)),"検査",IF(ISNUMBER(FIND("検査",A1)),"検査",IF(ISNUMBER(FIND("発注",A1)),"購入",IF(ISNUMBER(FIND("購入",A1)),"購入",IF(ISNUMBER(FIND("経費",A1)),"購入,"IF(ISNUMBER(FIND("配布用",A1)),"購入","その他"))))) わかる方がいらっしゃいましたら、どうぞ教えて下さい。

  • ExcelのVBAがオーバーフローに!?

    読んで頂きありがとうございます。 以前に質問しました時に回答を頂き凄く助かっていたのですが、何故か「オーバーフロー」と表示されてしまいます。 ひょっとしたら桁なのかも知れません。 下記のVBAを教えて頂きしようしていました。 Option Explicit Sub Test() Dim c(), p(), q(), i, j, l, r, k As Long r = Range("B2").End(xlDown).Row l = Range("D2").End(xlDown).Row ReDim c(r - 2), p(r - 2), q(r - 2) For i = 1 To r - 2 c(i) = Cells(i + 2, 2).Value p(i) = Cells(i + 2, 3).Value q(i) = i + 2 Next i For i = 1 To r - 3 For j = i + 1 To r - 2 If c(i) > c(j) Then k = c(i) c(i) = c(j) c(j) = k k = p(i) p(i) = p(j) p(j) = k k = q(i) q(i) = q(j) q(j) = k End If Next j Next i For i = 1 To r - 2 Cells(i + 2, 7).Value = c(i) For j = 3 To r If Cells(j, 4).Value = c(i) Then Cells(i + 2, 8).Value = p(i) - Cells(j, 5).Value If p(i) - Cells(j, 5).Value <> 0 Then Range("B" & q(i)).Interior.ColorIndex = 6 Range("D" & j).Interior.ColorIndex = 6 End If Exit For End If Next j Next i For i = 3 To r k = 0 For j = 3 To l If Cells(i, 2).Value = Cells(j, 4).Value Then k = 1 Exit For End If Next j If k = 0 Then Range("B" & i).Interior.ColorIndex = 35 End If Next i For i = 3 To l k = 0 For j = 3 To r If Cells(i, 4).Value = Cells(j, 2).Value Then k = 1 Exit For End If Next j If k = 0 Then Range("D" & i).Interior.ColorIndex = 35 End If Next i End Sub デパックのClickすると15行目辺りの「k = c(i)」が黄色くなります。 正直言ってマクロとか全く解りませんが、コピーして使っていました。 どこをどう変更すれば良いのか教えて頂ければ助かります。 よろしくお願いします。