プロが教える店舗&オフィスのセキュリティ対策術

条件付き書式以外でセル比較して一致しないものを太字に変えたい(VBA)

sheet1とsheet2のAI9:CD5000にそれぞれ数字が入力されてます。
同じセルで数字が違うsheet2セルを太文字に変えたいです。
条件付き書式を使えば楽なのですが、すでに作ってあるVBA構文に追加したいのです。
最終的にsheet1は削除します。
VBAで条件付き書式設定して書式だけ残して条件付き書式を削除しようとしましたがうまく行きませんでした。

条件付き書式以外で比較して太字に変える構文をご教授頂けないでしょうか?

A 回答 (4件)

No.3です。



細かい検証はしてませんが・・・
ある範囲の最初の行番号・最終行番号・最初の列番号・最後の列番号
はそれぞれ変数ですでに取得済みなのですね。

前回のコードは配列にセル範囲を格納し、その中でループさせていますので
シートのセル上でループさせるより格段に速く検索できます。
そして、ループさせるのは行・列とも配列の1番目~最後(行数・列数)となりますので
その辺の数合わせだけの問題です。

>For j = 1 To lastCol - myRngCol
では最終列が除外されるのでは?
>For j = 1 To lastCol - myRngCol + 1
にする必要があると思います。

次に今回の場合は配列の配置とセルの配置が一緒なので、
>wS2.Cells(i + myRngRow -1, j + wS2.Range(wS2.Cells(1, myRngCol - 1).Column))).Font.Bold = True
のようにセル番地内でシートを指定する必要はないはずです。
必要なのは「行番号」と「列番号」を合わせるだけです。

>wS2.Cells(i + myRngRow - 1, j + myRngCol - 1).Font.Bold = True

にしたらどうなりますか?

※ 最初に記載したように未検証なので
お望みどおりにならなかったらごめんなさい。m(_ _)m
    • good
    • 0
この回答へのお礼

ありがとうございました。
勉強になります。
意図通りの結果になりました。

お礼日時:2019/07/10 10:48

こんにちは!



セル数としては約24万セルの比較になるのですね。
無理やりやってみました。
標準モジュールにしてください。

Sub Sample1()
 Dim i As Long, j As Long
 Dim wS1 As Worksheet, wS2 As Worksheet
 Dim myR1, myR2

  Application.ScreenUpdating = False
   Set wS1 = Worksheets("Sheet1")
   Set wS2 = Worksheets("Sheet2")
    myR1 = wS1.Range("AI9:CD5000")
    myR2 = wS2.Range("AI9:CD5000")
     For i = 1 To UBound(myR1, 1) '//←9行目~5000行目まで//
      For j = 1 To 48 '//←AI列~CD列まで
       If myR1(i, j) <> myR2(i, j) Then
        wS2.Cells(i + 8, j + Range("AH1").Column).Font.Bold = True
       End If
      Next j
     Next i
  Application.ScreenUpdating = True
   MsgBox "完了"
End Sub

※ まずないとは思いますが、すべてのセルが異なった場合で
約34秒かかりました。m(_ _)m
    • good
    • 0
この回答へのお礼

ありがとうございました。
動作させることができました。
ご教授いただきました内容で、"AI9:CD5000"を変数にするやり方を合わせてご教授いただけないでしょうか。
自分なりに変更してみたところ、RANGEメソッドエラーになってしまう箇所が2か所ありました。

Sheet1がアクティブになっている状態の時です。
lastRow・・・最終行の数値が入ってます。(5000)
lastCol・・・最終列の数値が入ってます。(82)
myRngRow・・・最初の行の数値が入ってます。(9)
myRngCol・・・最終の列の数値が入ってます。(35)

myR2 = wS2.Range("AI9:CD5000")

myR2 = wS2.Range(Cells(myRngRow , myRngCol ), Cells(lastRow, lastCol))
これだとエラーになったので、
myR2 = wS2.Range(wS2.Cells(myRngRow , myRngCol ), wS2.Cells(lastRow, lastCol))
ここに関してはこれで解決しました。

For j = 1 To 48

For j = 1 To lastCol - myRngCol
特に問題なし

wS2.Cells(i + 8, j + Range("AH1").Column).Font.Bold = True

wS2.Cells(i + myRngRow -1, j + Range(Cells(1, myRngCol - 1).Column))).Font.Bold = True
これだとエラーになったので、
wS2.Cells(i + myRngRow -1, j + wS2.Range(wS2.Cells(1, myRngCol - 1).Column))).Font.Bold = True
これでもエラーでした。ここに関してどうすればいいか苦慮してます。

お礼日時:2019/07/09 19:28

こんにちは



>VBAで条件付き書式設定して書式だけ残して
>条件付き書式を削除しようとしましたが~
それだけ複雑な処理を試みようとなさっているのですから、ご質問の内容をそのまま処理するのはさほどのものでもないでしょう。

No1様が指摘なさっているように、範囲がそれなりなので、若干時間が掛かるかも知れませんが、単純に全てのセル範囲の値を順に比較すればよいだけです。
ワークシートをそれぞれws1、ws2、行をr、列をcとするなら
 ws2.Cells(r, c).Font.Bold = (ws1.Cells(r, c).Value = ws2.Cells(r, c).Value)
といった1行の処理をループさせれば済むと思います。

あるいは、For Eachで処理すれば、記述はもっと簡単になるかもしれません。
ws2の対象範囲内のセルをcとするなら、上記と同じ内容は
 c.Font.Bold = (c.Value = ws1.Cells(c.Address).Value)
のように表せることになります。

※ 結合セルの有無や表示書式の違いによる見た目の差異等は考慮していません。
 (単純にセルの値の比較だけを行っています)
※ 処理時間の短縮が必要な場合は、もう少し工夫が必要になりますね。
    • good
    • 0
この回答へのお礼

ありがとうございました。
いろいろ試してみたいと思います。

お礼日時:2019/07/09 19:11

条件付き書式を使わないとなると、条件付き書式で行っている処理の一つ一つを再現するしかないと思うんだ。



さすがに面倒なので、自分なら
 ・1セルずつ
 ・条件付き書式(条件が成立したら太字にする)を設定した後
 ・Font の状態を読み取って太字(Bold)なら、Font の Bold を 有効(True)にする
 ・条件付き書式を削除
…ような構造にするかな。
このほうがシンプルで間違いが少ないと思います。

ただし、結構な時間がかかるかも知れません。
ブレークポイントを設定しておきましょう。
    • good
    • 0
この回答へのお礼

ありがとうございました。
いろいろ試してみたいと思います

お礼日時:2019/07/09 19:10

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!