- ベストアンサー
エクセルVBAでセルの元の値の色を残したまま、新しく加えた文字列の色を変更する方法
タイトルがわかりづらくてすみません。 具体的には、次のような表とマクロがあった場合 A B 1 1 1 2 2 3 3 4 4 5 5 Sub test() Dim a, g As Integer Dim f As String a = 1 Do f = Cells(a, 2).Value g = Len(Cells(1, 1).Value) Cells(1, 1).Value = IIf(Cells(1, 1).Value <> "", Cells(1, 1).Value & "+" & f, f) Cells(1, 1).Characters(start:=g + 2, Length:=Len(f)).Font.ColorIndex = 3 a = a + 1 Loop Until Cells(a, 2).Value = "" End Sub セルA1には「1+2+3+4+5」という結果が入りますが、最後の「5」だけが赤文字になります。 そうではなくて、新たに加えた「2+3+4+5」の部分すべてを赤文字にするにはどうすればよいでしょうか。 つまり、ループの最初の結果をそのまま保持したいということです。 未熟者なのと、もっと大きなマクロの一部を質問用に抜き出したものなので、たどたどしい文法になっていますが、その辺は目をつぶってください。 どうかよろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
とりあえず現状のコードを活かすとすると下記のようにするだけで動きますよ Sub test() Dim a, g As Integer Dim f As String a = 1 g = Len(Cells(1, 1).Value) Do f = Cells(a, 2).Value Cells(1, 1).Value = IIf(Cells(1, 1).Value <> "", Cells(1, 1).Value & "+" & f, f) a = a + 1 Loop Until Cells(a, 2).Value = "" Cells(1, 1).Characters(Start:=g + 2, Length:=Len(Cells(1, 1)) - (g + 1)).Font.ColorIndex = 3 End Sub
その他の回答 (3)
- kenpon24
- ベストアンサー率64% (66/102)
話す場所が間違っているとは思いますがコメントさせていただきます。 IIFは個人的には好きではありません。さすがに数十倍は遅くなったことはありませんが。 例えば以下のようなコードがあった場合、上の方のIf文では問題なく処理できますが、下のIIF文ではエラーになってしまいます。 Sub testn() Dim st As String st = "" 'これはOK If Len(st) > 0 Then st = Mid(st, 1, Len(st) - 1) Else st = "" End If 'こっちはNG st = IIf(Len(st) > 0, Mid(st, 1, Len(st) - 1), "") End Sub これがエラーを分岐で避けることができなくなる現象だと思います。 以下のようなコードがあった場合、デバッガで1ステップずつ実行すると testmとtestlが両方とも実行されているのがわかります。 st = IIf(Len(st) > 0, testm, testl) Function testm() As String testm = "a" End Function Function testl() As String testl = "b" End Function 右辺の式を全て評価してから結果を返すのがIIFなんだなぁと個人的に解釈しています。 だから普通のIF文なら回避できる箇所でエラーしてしまうのだろうと。 一見すっきり書けるように見えるIIF関数ですが、不要な処理を実行してしまう事になるので私はループの中ではあまり使いませんね。
お礼
何度もありがとうございます。 Iif関数は使わないようにします。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんばんは。 以下のわたしのマクロは、あまり、みなさんとかわり映えしません。少し、思ったことがあるので、書かせていただきました。 最近、他人のマクロで目立つ現象なのですが、ほんの数年前には、IIf 関数は、VBAでは使うなという暗黙のルールがありました。お疑いの方は、インターネット検索してみるとよいです。これは、Microsoft Help サイトにも書かれていたのですが、最近、調べたら、あまり詳しく書かれていなくなっていました。もともと、Access では、クエリでは使うのですが、VBAでは、あまり使われるものではありません。 IIf(Cells(1, 1).Value <> "", Cells(1, 1).Value & "+" & f, f) この内部は、オブジェクトになりますので、マクロ自体を数十倍も遅くしたり、エラーを分岐で避けることができないなどの欠点がありますから、なるべく使わないようにする、というのが、以前には、言われていました。 Sub Test03() Dim org As Range Dim buf As String Dim i As Integer Dim j As Integer Dim o As Integer Set org = Range("A1") For i = 1 To Range("B65536").End(xlUp).Row If IsNumeric(Cells(i, 2).Value) Then buf = buf & "+" & Cells(i, 2).Value End If Next i o = Len(org.Text) + 1 j = Len(buf) org.Value = org.Text & buf '新たに加えた部分すべてを赤文字 org.Characters(Start:=o, Length:=j).Font.ColorIndex = 3 End Sub
お礼
確かに、IIf関数を使うと、解決不能(?)なエラーが出ることが時々あります。 考えてもわからないので、If関数に書き直していましたが、私の未熟さだけが原因ではなかったんですね(苦笑 これからはIif関数は使わないようにします。 どうもありがとうございました。
- hige_082
- ベストアンサー率50% (379/747)
質問のコードを生かすと こんな感じかな? Sub test01() Dim a As Integer, g As Integer Dim f As String Dim i As Integer a = 1 Do f = Cells(a, 2).Value Cells(1, 1) = IIf(Cells(1, 1).Value <> "", Cells(1, 1).Value & "+" & f, f) g = Len(Cells(1, 1).Value) For i = 3 To g Step 2 Cells(1, 1).Characters(Start:=i, Length:=Len(f)).Font.ColorIndex = 3 Next i a = a + 1 Loop Until Cells(a, 2).Value = "" End Sub 私が作るなら、こんな感じ Sub test02() Dim i As Integer, ii As Integer Dim f As Integer With Range("A1") f = IIf(Len(.Value) = 0, 1, Len(.Value)) For i = 1 To Range("B65536").End(xlUp).Row .Value = IIf(.Value = "", Cells(i, 2).Value, .Value & "+" & Cells(i, 2).Value) Next i ii = InStr(f, .Value, "+") + 1 For i = ii To Len(.Value) If .Characters(Start:=i, Length:=1).Caption <> "+" Then .Characters(Start:=i, Length:=1).Font.ColorIndex = 3 End If Next i End With End Sub B列のデータ桁や行数を変化させたり 連続で実行すると面白いかも 違いが分ると思います 参考まで
お礼
自作までしていただいてありがとうございます。 こちらも試してみたいと思います。 お世話になりました。
お礼
なるほど。 赤文字部分の長さに注目すればよかったんですね。 ありがとうございました。