質問するログイン新規登録

回答編集履歴

2

ついき

2019/02/28 05:41

投稿

jawa
jawa

スコア3021

answer CHANGED
@@ -25,4 +25,106 @@
25
25
  こうすることで、ループの中で文字(例えば10文字中の7文字目)を削っても、それ以降に処理する文字列(6文字目より前)には影響を与えないので、独自にカウンタを取る必要がなくなります。
26
26
  これにより条件を満たすまでループするDo~Loopではなく、For~Nextの有限ループで記述できるので無限ループのリスクを回避できるというわけです。
27
27
 
28
- 参考になれば幸いです。
28
+ 参考になれば幸いです。
29
+
30
+ (追記)
31
+ ---
32
+ 256文字ずつ取り出して処理する方法ですが、かなり面倒なことになってしまいました。
33
+ もう少しシンプルにできないものでしょうかね・・。
34
+ ```
35
+ Sub removeStrikethrough()
36
+ Dim tmpRange As Range
37
+ Dim i, tmpLength As Long
38
+ Dim iCnt As Integer
39
+ Dim iIdx As Integer
40
+
41
+ Dim cWk1 As Range '作業用①:256文字ずつ取り出すセル
42
+ Dim cWk2 As Range '作業用②:処理結果を連結するセル
43
+ Dim cOrg As Range '作業用③:元の内容を保管するセル
44
+
45
+ Set cOrg = Cells(1, 1) '使っていないセル(A1)
46
+ Set cWk1 = Cells(2, 1) '使っていないセル(A2)
47
+ Set cWk2 = Cells(3, 1) '使っていないセル(A3)
48
+
49
+ '速度向上のため処理中の画面更新をOFF
50
+ Me.Application.ScreenUpdating = False
51
+
52
+ For Each tmpRange In Selection
53
+
54
+ '結合セルは先頭セルでのみ処理する
55
+ If tmpRange.Address <> tmpRange.MergeArea(1).Address Then Exit For
56
+
57
+ tmpLength = Len(tmpRange.MergeArea(1).Value)
58
+
59
+ '元のセルを作業用③セルにコピーする
60
+ tmpRange.Copy cOrg
61
+ '元のセルはクリアする(結果を出力するため)
62
+ tmpRange = ""
63
+
64
+ '後ろから256文字ずつ取り出すループ
65
+ For iCnt = Int((tmpLength - 1) / 256) To 0 Step -1
66
+
67
+ '作業用③から①に256文字を転記
68
+ cWk1 = cOrg.Characters(1 + (256 * iCnt), 256).Caption
69
+
70
+ '作業用③セルから作業用①セルへ書式を反映
71
+ For i = 1 To 256
72
+ iIdx = i + (256 * iCnt)
73
+ If iIdx > tmpLength Then Exit For
74
+
75
+ 'フォントのコピー
76
+ Call prcCopyFont(cWk1, i, cOrg.Characters(iIdx, 1).Font)
77
+
78
+ Next i
79
+
80
+ '作業用①セルから取り消し線の文字を削除する
81
+ For i = Len(cWk1) To 0 Step -1
82
+ If cWk1.Characters(i, 1).Font.Strikethrough Then
83
+ cWk1.Characters(i, 1).Delete
84
+ End If
85
+ Next
86
+
87
+ '元セル(現時点での結果セル)の内容を作業用②セルに出力する
88
+ tmpRange.Copy cWk2
89
+
90
+ '元セル(現時点での結果セル)に作業用①と作業用②の内容を連結する。
91
+ tmpRange = cWk1.Text & cWk2.Text
92
+
93
+ '作業用①の書式を反映する
94
+ For iIdx = 1 To Len(cWk1)
95
+ 'フォントのコピー
96
+ Call prcCopyFont(tmpRange, iIdx, cWk1.Characters(iIdx, 1).Font)
97
+ Next
98
+ '作業用②の書式を反映する
99
+ For iIdx = 1 To Len(cWk2)
100
+ 'フォントのコピー
101
+ Call prcCopyFont(tmpRange, iIdx + Len(cWk1), cWk2.Characters(iIdx, 1).Font)
102
+ Next
103
+ Next iCnt
104
+
105
+ Next
106
+
107
+ cOrg.Clear
108
+ cWk1.Clear
109
+ cWk2.Clear
110
+
111
+ '画面更新をON
112
+ Me.Application.ScreenUpdating = True
113
+
114
+ End Sub
115
+
116
+ 'フォントをコピーする関数
117
+ Sub prcCopyFont(ByRef vCell As Range, ByVal vIndex As Integer, ByVal vFont As Font)
118
+
119
+ With vCell.Characters(vIndex, 1).Font
120
+ .Bold = vFont.Bold
121
+ .Color = vFont.Color
122
+ .Italic = vFont.Italic
123
+ .Name = vFont.Name
124
+ .Size = vFont.Size
125
+ .Underline = vFont.Underline
126
+ .Strikethrough = vFont.Strikethrough
127
+ End With
128
+
129
+ End Sub
130
+ ```

1

しゅうせい

2019/02/28 05:41

投稿

jawa
jawa

スコア3021

answer CHANGED
@@ -10,7 +10,8 @@
10
10
 
11
11
  ループの問題
12
12
  ---
13
- もうひとつ、これはテクニックになるのですが、今回のように「文字を削除していく」とか「行を削除していく」といったように「対象を削っていくループ処理」では、ループを逆順で回た方処理が安全かつ楽な処理になります。
13
+ もうひとつ、これはテクニックになるのですが、今回のように「文字を削除していく」とか「行を削除していく」といったように「対象を削っていくループ処理」を前方から順に処理していくと、ループをしていく中で対象のインデックスずれていくことになります。
14
+ このような場合は、ループを逆順で回した方が安全かつ楽なコーディングで処理できます。
14
15
  今回の場合でいうと、逆順ループにしていれば、少なくとも無限ループに陥ることはありませんでした。
15
16
 
16
17
  ```