• ベストアンサー

エクセル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」の部分すべてを赤文字にするにはどうすればよいでしょうか。 つまり、ループの最初の結果をそのまま保持したいということです。 未熟者なのと、もっと大きなマクロの一部を質問用に抜き出したものなので、たどたどしい文法になっていますが、その辺は目をつぶってください。 どうかよろしくお願いします。

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

  • ベストアンサー
  • kenpon24
  • ベストアンサー率64% (66/102)
回答No.1

とりあえず現状のコードを活かすとすると下記のようにするだけで動きますよ 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

cs-megami
質問者

お礼

なるほど。 赤文字部分の長さに注目すればよかったんですね。 ありがとうございました。

その他の回答 (3)

  • kenpon24
  • ベストアンサー率64% (66/102)
回答No.4

話す場所が間違っているとは思いますがコメントさせていただきます。 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関数ですが、不要な処理を実行してしまう事になるので私はループの中ではあまり使いませんね。

cs-megami
質問者

お礼

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

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

こんばんは。 以下のわたしのマクロは、あまり、みなさんとかわり映えしません。少し、思ったことがあるので、書かせていただきました。 最近、他人のマクロで目立つ現象なのですが、ほんの数年前には、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

cs-megami
質問者

お礼

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

  • hige_082
  • ベストアンサー率50% (379/747)
回答No.2

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

cs-megami
質問者

お礼

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

関連するQ&A

  • VBA For Eachでセル内の文字列を一個ずつ取り出すには

    エクセル2000です。 たとえばA1セル内の文字列を一個ずつ取り出す場合、 Sub test01() For i = 1 To Len(Range("A1").Value) Cells(i, "B").Value = Range("A1").Characters(i, 1).Text Next End Sub このように最初から最後の文字まで何番目で指定することはわかるのですが、これをFor Each で回すにはどうしたらよいでしょうか? (⌒o⌒)? お教えください。 Sub test02() For Each ch In Range("A1").Characters i = i + 1 Cells(i, "B").Value = ch Next End Sub ではエラーになります。

  • VBA 文字列に関して

    現在 A22のセルに入力された文字列をボタンを押せば ばらばらにしてA22のセルから順番に入れるマクロを作りました (例)A22のセルに ”こんにちわ”の文字列が入っている場合 ボタン押下   ↓ A22のセル⇒こ B22のセル⇒ん C22のセル⇒に D22のセル⇒ち E22のセル⇒わ になる。 不思議なことに数字を16文字以上いれてボタンを押し文字を分離すると入力していない文字、数字が入ってしまいます。 数字だけこういう現象が発生してしまいます。 例えば "1111111111111111"と入力して文字を分離した場合 1.11111111111111E+15と個々のセルに格納されます。 原因がわかる方、教えて頂けないでしょうか? 以下がコードです。宜しくお願い致します。 Private Sub CommandButton1_Click()   Dim one As String   Dim myString As String   myString = Cells(22, 1)   numString = Len(Cells(22, 1))   If Len(myString) <= 50 Then    For i = 1 To Len(Range("A22").Value)      one = String(1, myString)      Cells(22, i) = one      myString = Replace(myString, one, "", 1, 1, vbTextCompare)    Next i   End If End Sub

  • エクセル セルの文字列の有無からほかのセルに数値を

    勤務リスト.xlsx におきまして セルE1に、午前休、 という文字列があれば セルF1に数値の0 セルG1に数値の2000 を入力 同様に セルEiに、午前休、 という文字列があれば セルFiに数値の0 セルGiに数値の2000 31日を計算にいれて iを1から30としました エクセルファイルの開発から マクロに行き 以下のコードをいれましたが ------------------------------- Sub 午前休み() Dim 選択シート As Sheets Dim i As Integer Set 選択シート = ActiveWindow.SelectedSheets If InStr(Cells(5, i), "午前休") > 0 Then Cells(6, i).Value = 0 Cells(7, i).Value = 2000 i = 1 Do Until i = 30 i = i + 1 Loop End If End Sub 上記 作動しません すみません 御教示くださいませ win10 office365

  • Excel VBAで文字列の部分一致の文字列を表示

    以前、こちらで頭5文字までの一致で文字列を表示するVBAを教えて頂きました。今回はFINDなどの部分一致での文字列を表示することをしたいのですが、ご教示いただけますと幸いです。 下記はSheet1のA3に文字を5文字以内いれるとSheet2のC列からピックアップしてSheet1のA列に文字列を表示する及びSheet2のB列のデータをSheet1のC列に表示させるVBAです。 Sub Test2() Dim Ws1 As Worksheet, Ws2 As Worksheet Dim SData As String, i As Long, VRet As Variant Dim c As Range, LastRow As Long Set Ws1 = Sheets("Sheet1") Set Ws2 = Sheets("Sheet2") SData = CStr(Ws1.Range("A3").Value) If SData = "" Then Exit Sub i = 5 LastRow = Ws1.Cells(Rows.Count, "A").End(xlUp).Row If LastRow < i Then LastRow = i End If Ws1.Range(Ws1.Cells(i, "A"), Ws1.Cells(LastRow, "C")).ClearContents With Ws2 For Each c In .Range(.Cells(1, "C"), .Cells(Rows.Count, "C").End(xlUp)) VRet = InStr(1, CStr(c.Value), SData, vbTextCompare) If VRet = 1 And Len(c.Value) >= 10 Then Ws1.Cells(i, "A").Resize(1, 2).Value = c.Resize(1, 2).Value 'とりあえずSheet2のB列のデータ(C列のデータに同期したデータ)をSheet1のC列に Ws1.Cells(i, "C").Value = .Cells(c.Row, "B").Value i = i + 1 End If Next End With End Sub 宜しくお願い致します。

  • エクセルVBAの記述方法の質問です。

    エクセルです。12個のセルの文字列をオートシェープの吹き出しに順に表示させるマクロをつくりました。 Sub tenki2() Dim i As Integer Dim a As String For i = 1 To 12 a = Cells(i, 2).Value ActiveSheet.Shapes("AutoShape 4").Select Selection.Characters.Text = a Application.Wait Now + TimeValue("00:00:05") Next i End Sub これで思った通り表示されるのですが、できればオートシェープをセレクトしないようにしたいのです。 (シートを保護するため) それで ActiveSheet.Shapes("AutoShape 4").Select Selection.Characters.Text = a のところを ActiveSheet.Shapes("AutoShape 4").Characters.Text = a と変えたのですが、「オブジェクトはこのプロパティまたはメソッドをサポートしていません」という実行時エラーがでてしまいました。書き方のどこがまずかったのでしょうか?ご教示いただければ幸いです。

  • エクセル2007 参照セルの値が認識されない

    エクセル2007の環境で下記マクロを実行すると、 アクティブシートのセルA1に数字が入っている場合、Sheet1のセルA1に値を転記しても そのセルA1の値をVLOOKUP関数で参照できません。 マクロに問題があるためなのか何処に問題があるのか分からないので教えてください。 宜しくお願いいたします。 【sheet】は アクティブシートの3行目から1000行目までのA列のセルをクリックしたらセルA1に値を表示 その後、下記【モジュール】を使用し、 アクティブシートのセルA1が空白の場合、 A列の数値をSheet1のセルA1に転記し、アクティブシートのA列の数値が空白になるまで循環する。 Sheet1のセルA1の値をVLOOKUP関数で参照した内容を表示、印刷します。 ----------------------------------------------------------------- '【sheet】 Private Sub Worksheet_SelectionChange(ByVal Target As Range) With Target If .Count > 1 + IsEmpty(.Value) Then Exit Sub If Application.Intersect(.Cells, Range("A3:A1000")) Is Nothing Then Exit Sub ActiveSheet.Cells(1, 1).Value = .Value End With End Sub ----------------------------------------------------------------- '【モジュール】 Sub TEST() Dim myBtn As Integer Dim myMsg As String, myTitle As String Dim WS1 As Worksheet, WS2 As Worksheet Dim i As Long myMsg = "●●●" myTitle = "確 認" myBtn = MsgBox(myMsg, vbYesNo + vbExclamation, myTitle) If myBtn = vbYes Then Set WS1 = ActiveSheet Set WS2 = Sheet1 If WS1.Cells(1, 1).Value = "" Then With WS1 For i = 3 To 65536 If .Cells(i, 1).Value = "" Then Exit For WS2.Cells(1, 1).Value = .Cells(i, 1).Value WS2.Cells(1, 2).Value = ActiveSheet.Name 'WS2.PrintOut Copies:=1 Next i End With ElseIf WS1.Cells(1, 1).Value >= 1 Then WS2.Cells(1, 1).Value = WS1.Cells(1, 1).Value WS2.Cells(1, 2).Value = WS1.Name 'WS2.PrintOut Copies:=1 Else End If End If End Sub -----------------------------------------------------------------

  • VBAでセルの色付を別の列にも追加するには

    WINDOWS XP EXCELL 2003です。 いつもお世話になります。 現在下記の如く、 A列にマクロを設定しています。 ※A F列には下記の数式が入っています。 A2 =IF(B2="","",TEXT(B2,"mm")) F2 =IF(G2="","",TEXT(G2,"mm")) Private Sub Worksheet_Change(ByVal Target As Range) If Target.Row >= 2 And Target.Address = Cells(Rows.Count, "C").End(xlUp).Address Then Target.Offset(0, -1).Value = Date End If Dim c As Integer If Target.Column <> 2 Then Exit Sub If Target.Value = "" Then c = 0 Else On Error GoTo line Select Case Month(Target.Value) Case 1: c = 46 Case 2: c = 4 Case 3: c = 39 Case 4: c = 6 Case 5: c = 7 Case 6: c = 8 Case 7: c = 43 Case 8: c = 3 Case 9: c = 44 Case 10: c = 24 Case 11: c = 40 Case 12: c = 17 End Select End If Target.Offset(0, -1).Interior.ColorIndex = c Target.Offset(0, -1).Font.ColorIndex = IIf(c = 1, 2, 0) Exit Sub line: Target.Offset(0, -1).Interior.ColorIndex = 0 Target.Offset(0, -1).Font.ColorIndex = 0 End Sub 上記のマクロに追加でF列にも同様にセルの色付けするにはどうすればいいか ご教授を御願いできないでしょうか。

  • Excelで複数セルからの文字の結合

    B列からF列までのセルの内容を結合してH列に表示させるため、 以下のVBAを使用したのですが、結果が上手くいきません 原因など分かりましたら、指摘をお願いします マクロの内容 Sub test01() Dim c As Range Dim i As Long With ActiveSheet i = 1 Do While .Cells(i, "A") <> "" If .Cells(i, "A") <> "" Then For Each c In .Range(.Cells(i, "B"), .Cells(i, "B").Cells(i, "F")) .Cells(i, "H") = IIf(.Cells(i, "H") = "", c, .Cells(i, "H") & "/" & c) Next c Else .Cells(i, "H") = .Cells(i, "B") End If i = i + 1 Loop End With End Sub シートの内容  ABCDEFGH 1 1あいうえお 2 2か くけこ 3 3さし せそ 実行の結果 あ/い/う/え/お/ か/き/く/け/こ//さ/し//せ/そ/ さ/し//せ/そ///////////// 上記のようになってしまいます 2行目の「か/き/く/け/こ」の後に1行下の「さ/し//せ/そ」 が入っている状態です よろしくお願いします

  • Excel VBA でテキストボックスの値をセルA列から検索

    いつもお世話になります。 Private Sub CommandButton3_Click() Dim 行 As String Dim 列 As String Dim 最終行 As String Dim 検索行 As String Dim メッセージ As Integer Dim 一致 As Range Dim myNO As Variant Dim i As Long Sheets(3).Select 最終行 = Range("A2").End(xlDown).Offset(1).Select 行 = ActiveCell.Row 列 = ActiveCell.Column myNO = TextBox2.Value 検索行 = Range("A2").End(xlDown).Select ※・・・Set 一致 = Range("A2:検索検").Findwhat:=TextBox2,lookat:=xlWhole) If 一致 Is Nothing Then MsgBox "データがありません。新規コード入力します。" Cells(行, 列 + 0) = UserForm1.TextBox2.Value Cells(行, 列 + 1) = UserForm1.ComboBox7.Value Else i = Cells(行 - 1, "A") Cells(i, 列 + 0) = UserForm1.TextBox2.Value Cells(i, 列 + 1) = UserForm1.ComboBox7.Value End If End Sub 「エラー1004'Range'メソッドは失敗しました'Global'オブジェクト」とでます。※印が黄色になっています。 ユーザーフォーム1のテキストボックスの値をシート3のA列から検索して、一致すれば、A列の一致セルに上書き入力して、一致が無い場合はA列の空白セルに追加入力したいのです。よろしくお願い致します。

  • (VBA)文字列を指定位置から抜き出す

    Office2019,Windows10 文字列の指定位置から文字列の最後までを抜き出すコード(文字列())を作成しました。 現在は、指定文字列位置を指定するのに目で数えて指定しますが  数え間違えが多いのでミスを少なくする方法を検討しました。 以前教えてもらったコード(Nubering3())が利用したいのですが、 イメージだけでどうしたらいいか分かりません。 イメージとしては、  1)range(A1)の文字列で添付画像のような画像を表示して、   画像の下部に「どこから? 数値を入力してください」と表示して   抜き出し開始位置の数値を入力する   添付画像のように文字数が多くなると行が長くなるので    40文字毎に改行されて表示させる    (改行が難しい場合は、それに代わる方法でもOKです。)  2)数値が入力されれば、最初の画像(のような)は消えて     B列に抜き出し結果が表示される。 ---------------------------------------------------------------- Sub Mid文字列() Dim MojiSuu As Single Dim KokoKara As Variant Dim I As Single Dim Nukidashi As String Dim EndRow As Single EndRow = Cells(1, "A").End(xlDown).Row KokoKara = Application.InputBox(prompt:="どこから? 数値を入力してください", Title:="数値入力", Type:=1) If TypeName(KokoKara) = "Boolean" Then MsgBox "数値以外が入力されたので終了します。" Exit Sub End If For I = 1 To EndRow MojiSuu = Len(Range("A" & I)) Nukidashi = Mid(Range("A" & I), KokoKara, MojiSuu) Range("B" & I) = L Next I End Sub --------------------------------------------------------------- Sub Nubering3() Dim Ws1 As Worksheet, Ws2 As Worksheet Dim i As Long, j As Long, WRow As Long Dim uRows As Range, uRange As Range Set Ws1 = Sheets("DATA") Set Ws2 = Sheets("Number") Set uRows = Ws2.Rows(1) Set uRange = Ws2.Range("A2") 'Numberシートの初期化(全体=数式・文字・書式・コメント全てをクリア) Ws2.Range("A1:XX100").Clear Application.ScreenUpdating = False For i = 2 To Ws1.Cells(Rows.Count, "A").End(xlUp).Row WRow = Ws2.Cells(Rows.Count, "A").End(xlUp).Row + 1 If Ws2.Range("A1").Value = "" And WRow = 2 Then WRow = 1 End If Set uRows = Union(uRows, Ws2.Rows(WRow)) For j = 1 To Len(Ws1.Cells(i, "A").Value) Ws2.Cells(WRow, j).Value = j Ws2.Cells(WRow + 1, j).Value = Mid(Ws1.Cells(i, "A").Value, j, 1) Set uRange = Union(uRange, Ws2.Cells(WRow + 1, j)) Next Next i 'Numeling 大文字、中央揃え uRows.HorizontalAlignment = xlCenter uRows.Font.Bold = True '分割文字中央揃え罫線外枠 uRange.HorizontalAlignment = xlCenter uRange.Borders.LineStyle = xlContinuous 'セル幅を見やすく Ws2.Range("A1:xx100").ColumnWidth = 3 Application.ScreenUpdating = True Ws2.Activate Set Ws1 = Nothing Set Ws2 = Nothing Set uRows = Nothing Set uRange = Nothing End Sub

専門家に質問してみよう