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

質問編集履歴

1

載せていたコードの範囲を広げました

2021/04/21 04:33

投稿

kktok
kktok

スコア23

title CHANGED
File without changes
body CHANGED
@@ -19,6 +19,257 @@
19
19
  原因が分からず、お教えいただけますと幸いです。
20
20
 
21
21
  ```VBA
22
+ 'inTSはobjFSO.OpenTextFileで読み込んだ対象データ、targetColNameは判定列の名前、targetKeyArr()は集計対象外となる条件群、targetFolderPath はCSVのパス
23
+ Sub trimCsvOrg2(ByRef inTS As Variant, ByVal targetColName As String, ByRef targetKeyArr() As String, targetFolderPath As String)
24
+
25
+ Dim currentRow As Long, currentColumn As Long, indexChara As Long
26
+ Dim lngQuote As Long
27
+ Dim strTarget As String
28
+ Dim targetColumn As Long
29
+ Dim isAdd As Boolean: isAdd = True
30
+ Dim strArr() As String
31
+ Dim strRec As String
32
+ Dim test1 As Long
33
+ Dim resultCSV As Workbook
34
+ Dim strResults() As String
35
+ Dim dimenNum As Long
36
+ Dim startR As Long: startR = 1
37
+ Dim countThrough As Long: countThrough = 0
38
+ Dim countColumn As Long: countColumn = 100000
39
+
40
+ Set resultCSV = returnWB(targetFolderPath)
41
+
42
+ currentRow = 1 'シートの1行目から出力
43
+ currentColumn = 0 '列位置はupdateConditionsでカウントアップ
44
+ lngQuote = 0 'ダブルクォーテーションの数
45
+ targetColumn = 0 '列番号の初期化
46
+ strTarget = ""
47
+
48
+ Do While Not inTS.AtEndOfStream
49
+
50
+ On Error GoTo err2
51
+
52
+ strRec = CStr(inTS.Read(1))
53
+
54
+ Select Case strRec
55
+
56
+ Case vbLf, vbCr '「"」が偶数なら改行、奇数ならただの文字
57
+
58
+ If lngQuote Mod 2 = 0 Then
59
+
60
+ strRec = strRec & CStr(inTS.Read(1)) '改行としてのCrが出てきたらLfも読み込んで捨てる
61
+
62
+ '行が変わる時の処理。追加判定が真なら1次元配列を2次元配列に突っ込む
63
+ If isAdd Then
64
+ Call pushValueToArr(strTarget, strArr) '成型した文字列を配列に格納
65
+ Call pushArrToMDArr(strResults, strArr, dimenNum, countColumn) '2次元配列に1次元配列を突っ込む
66
+ If currentRow = 1 Then countColumn = UBound(strArr)
67
+
68
+ '5000次元までいった時点でシートに差し込む
69
+ If dimenNum = 4999 Then
70
+
71
+ startR = pushArrToCells(resultCSV.Worksheets(1), startR, dimenNum, strResults)
72
+ dimenNum = 0
73
+
74
+ End If
75
+
76
+ Else
77
+
78
+ countThrough = countThrough + 1
79
+
80
+ End If
81
+
82
+ Erase strArr '1次元配列をリセットする
83
+
84
+ Call updateConditions(currentColumn, strTarget, lngQuote) '列が変わる時の処理
85
+ currentRow = currentRow + 1
86
+ isAdd = True
87
+ currentColumn = 0
88
+ lngQuote = 0
89
+
90
+ Else
91
+
92
+ strTarget = strTarget & strRec
93
+
94
+ End If
95
+
96
+ Case "," '「"」が偶数なら区切り、奇数ならただの文字
97
+
98
+ If lngQuote Mod 2 = 0 Then
99
+
100
+ If targetColumn = 0 Then Call getTargetColumnIndex(currentColumn, targetColumn, strTarget, targetColName) '項目行なら判定行のインデックスを探す
101
+ If currentRow > 1 And (currentColumn + 1) = targetColumn Then isAdd = Not isMemberInArr(targetKeyArr, strTarget)
102
+ If isAdd Then Call pushValueToArr(strTarget, strArr()) '成型した文字列を配列に格納
103
+ Call updateConditions(currentColumn, strTarget, lngQuote) '列が変わる時の処理
104
+
105
+ Else
106
+
107
+ strTarget = strTarget & strRec
108
+
109
+ End If
110
+
111
+ Case """" '「"」のカウントをとる
112
+
113
+ lngQuote = lngQuote + 1
114
+ strTarget = strTarget & strRec
115
+
116
+ Case Else
117
+
118
+ strTarget = strTarget & strRec
119
+
120
+ End Select
121
+
122
+ Loop
123
+
124
+ '最終セルの処理
125
+ If currentColumn > 0 And strTarget <> "" Then
126
+
127
+ If (currentColumn + 1) = targetColumn Then isAdd = isMemberInArr(targetKeyArr, strTarget)
128
+ If isAdd Then Call pushValueToArr(strTarget, strArr) '成型した文字列を配列に格納
129
+ Call updateConditions(currentColumn, strTarget, lngQuote) '列が変わる時の処理
130
+
131
+ End If
132
+
133
+ If Not Not strResults Then
134
+
135
+ Call pushArrToCells(resultCSV.Worksheets(1), startR, dimenNum, strResults)
136
+
137
+ End If
138
+
139
+ resultCSV.Save
140
+
141
+ err2:
142
+ MsgBox (err.Description)
143
+
144
+
145
+ End Sub
146
+
147
+ '対象列の値なら配列に追加する
148
+ '①現在の列インデックス②対象の文字列③ダブルクォーテーションの数④対象列名⑤対象列インデックス⑥文字列配列
149
+ Sub updateConditions(ByRef currentColumn As Long, ByRef strTarget As String, ByRef lngQuote As Long)
150
+
151
+ currentColumn = currentColumn + 1
152
+ lngQuote = 0
153
+
154
+ strTarget = ""
155
+
156
+ End Sub
157
+ '項目列が判定列ならインデックスを返す
158
+ Sub getTargetColumnIndex(ByVal currentColumn As Long, ByRef targetColumn As Long, ByVal strTarget As String, ByVal targetColName As String)
159
+
160
+ If editStrIsBlank(strTarget) = targetColName Then
161
+
162
+ targetColumn = currentColumn + 1
163
+
164
+ End If
165
+
166
+ End Sub
167
+
168
+ '空白なら""を、それ以外なら"を取った値に編集する
169
+ Function editStrIsBlank(ByVal strTarget As String)
170
+
171
+ If Left(strTarget, 1) = """" And Right(strTarget, 1) = """" Then
172
+
173
+ If Len(strTarget) <= 2 Then
174
+
175
+ editStrIsBlank = ""
176
+ Exit Function
177
+
178
+ Else
179
+
180
+ editStrIsBlank = Mid(strTarget, 2, Len(strTarget) - 2)
181
+ Exit Function
182
+
183
+ End If
184
+
185
+ End If
186
+
187
+ editStrIsBlank = strTarget
188
+
189
+ End Function
190
+
191
+ '文字列の"を削除、最大数を増やして1次元配列に値を入れる
192
+ Sub pushValueToArr(ByVal strTarget As String, ByRef strArr() As String)
193
+
194
+ strTarget = Replace(strTarget, """""", """") '前後の「"」を削除
195
+
196
+ strTarget = editStrIsBlank(strTarget) '空白なら""を、それ以外なら"を取った値に編集する
197
+
198
+ If Not Not strArr Then '配列が初期化済みなら上限数を増やして追加する
199
+
200
+ ReDim Preserve strArr(UBound(strArr) + 1)
201
+
202
+ Else
203
+
204
+ ReDim strArr(0)
205
+
206
+ End If
207
+
208
+ strArr(UBound(strArr)) = strTarget
209
+
210
+ End Sub
211
+
212
+ '1次元配列の値をすべて2次元配列に入れる(呼び出し元は最後にtransposeする)。1列目以降は次元数の横方向固定
213
+ Sub pushArrToMDArr(strResults() As String, strArr() As String, ByRef dimenNum As Long, ByVal countColumn As Long)
214
+
215
+ Dim temp As Variant
216
+ Dim errA As Variant
217
+
218
+ If countColumn = 100000 Then
219
+
220
+ countColumn = UBound(strArr)
221
+
222
+ End If
223
+
224
+ If Not Not strResults Then '配列が初期化済みなら上限数を増やして追加する
225
+
226
+ dimenNum = dimenNum + 1
227
+
228
+ End If
229
+
230
+ ReDim Preserve strResults(countColumn, dimenNum)
231
+
232
+
233
+ For i = 0 To countColumn
234
+
235
+ If i > UBound(strArr) Then
236
+
237
+ strResults(i, dimenNum) = ""
238
+
239
+ Else
240
+
241
+ strResults(i, dimenNum) = strArr(i)
242
+
243
+ End If
244
+
245
+ Next i
246
+
247
+ End Sub
248
+
249
+ '指定要素が配列のメンバーかどうか返す
250
+ Function isMemberInArr(targetKeyArr() As String, strTarget As String) As Boolean
251
+
252
+ Dim result As Variant
253
+
254
+ result = Filter(targetKeyArr(), strTarget)
255
+
256
+ isMemberInArr = (UBound(result) <> -1)
257
+
258
+ End Function
259
+
260
+ 'ワークブックを作る
261
+ Function returnWB(path As String) As Workbook
262
+
263
+ Dim wbResult As Workbook
264
+ Set wbResult = Workbooks.Add
265
+ wbResult.SaveAs fileName:=path & "編集済データ.csv", _
266
+ FileFormat:=xlCSV
267
+
268
+ Set returnWB = wbResult
269
+
270
+ End Function
271
+
272
+ '2次元配列をシート内に突っ込む
22
273
  Function pushArrToCells(ByRef ws As Worksheet, ByVal startR As Long, ByVal dimenNum As Long, ByRef strResults() As String) As Long
23
274
 
24
275
  With ws
@@ -27,9 +278,10 @@
27
278
 
28
279
  End With
29
280
 
30
- Erase strResults '配列の上限数を超えてしまうのを防ぐため張り付けたあとに一度リセットする
281
+ Erase strResults
31
282
 
32
283
  pushArrToCells = startR + dimenNum + 1
33
284
 
34
285
  End Function
286
+
35
287
  ```