プロが教えるわが家の防犯対策術!

タイトルがわかりづらくてすみません。
具体的には、次のような表とマクロがあった場合

  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」の部分すべてを赤文字にするにはどうすればよいでしょうか。
つまり、ループの最初の結果をそのまま保持したいということです。

未熟者なのと、もっと大きなマクロの一部を質問用に抜き出したものなので、たどたどしい文法になっていますが、その辺は目をつぶってください。
どうかよろしくお願いします。

A 回答 (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
    • good
    • 0
この回答へのお礼

なるほど。
赤文字部分の長さに注目すればよかったんですね。

ありがとうございました。

お礼日時:2009/05/12 11:05

話す場所が間違っているとは思いますがコメントさせていただきます。



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関数ですが、不要な処理を実行してしまう事になるので私はループの中ではあまり使いませんね。
    • good
    • 0
この回答へのお礼

何度もありがとうございます。
Iif関数は使わないようにします。

お礼日時:2009/05/12 11:13

こんばんは。



以下のわたしのマクロは、あまり、みなさんとかわり映えしません。少し、思ったことがあるので、書かせていただきました。

最近、他人のマクロで目立つ現象なのですが、ほんの数年前には、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
    • good
    • 0
この回答へのお礼

確かに、IIf関数を使うと、解決不能(?)なエラーが出ることが時々あります。
考えてもわからないので、If関数に書き直していましたが、私の未熟さだけが原因ではなかったんですね(苦笑
これからはIif関数は使わないようにします。

どうもありがとうございました。

お礼日時:2009/05/12 11:11

質問のコードを生かすと


こんな感じかな?
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列のデータ桁や行数を変化させたり
連続で実行すると面白いかも
違いが分ると思います

参考まで
    • good
    • 0
この回答へのお礼

自作までしていただいてありがとうございます。
こちらも試してみたいと思います。

お世話になりました。

お礼日時:2009/05/12 11:08

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