回答編集履歴

1

補足を受けての追記

2015/10/22 00:27

投稿

jawa
jawa

スコア3013

test CHANGED
@@ -79,3 +79,253 @@
79
79
 
80
80
 
81
81
  ルールさえはっきりすれば実現可否や方法等アドバイスできると思いますので、よろしくお願いします。
82
+
83
+
84
+
85
+ ---
86
+
87
+ 【補足を受けての追記】
88
+
89
+
90
+
91
+ 大きく分けて2つの処理が必要になると思います。
92
+
93
+  ①元データを読み込みソートする
94
+
95
+  ②出力レイアウトの形に変更する
96
+
97
+
98
+
99
+
100
+
101
+ ①ソートの処理にはいくつか方法があります。
102
+
103
+  例ではExcelシートに出力してExcel機能でソートしていますが、作業用シートを使いたくない場合などはADOを利用する方法などもあります。
104
+
105
+
106
+
107
+ ```
108
+
109
+ '--定数宣言--
110
+
111
+ Enum W_ROWS
112
+
113
+ Title = 1 'タイトル行
114
+
115
+ DataStart 'データ開始行
116
+
117
+ End Enum
118
+
119
+
120
+
121
+ Enum W_COLS 'ソート用作業シートの列(取得CSVの項目順)
122
+
123
+ Name = 1 '名前
124
+
125
+ Kubun '識別区分
126
+
127
+ DateSart '日付の先頭列
128
+
129
+ End Enum
130
+
131
+
132
+
133
+ Enum O_COLS '出力シートの列
134
+
135
+ Name = 1 '名前
136
+
137
+ Date '日付
138
+
139
+ C '前日c判定
140
+
141
+ TIME_A 'aの時間
142
+
143
+ TIME_B 'bの時間
144
+
145
+ LAST '最終列判定用
146
+
147
+ End Enum
148
+
149
+ ```
150
+
151
+
152
+
153
+ ```
154
+
155
+ '--①CSVファイルの読み込み・ソート--
156
+
157
+ wsWorkSheet = WorkSheets("Sheet1")
158
+
159
+ wsWorkSheet.Activate
160
+
161
+
162
+
163
+ iFree = FreeFile '空き番号を取得
164
+
165
+ Open "CSVファイル名" For Input As iFree 'CSVファイル(元データ)をオープン
166
+
167
+
168
+
169
+ lRow = 0
170
+
171
+ Do Until EOF(iFree)
172
+
173
+ '1行読み込み
174
+
175
+ Line Input #iFree, strLine
176
+
177
+ lRow = lRow + 1
178
+
179
+
180
+
181
+ 'カンマ区切りで項目ごとに分割して配列に格納
182
+
183
+ Dim strSplit() As String
184
+
185
+ strSplit = Split(strLine, ",")
186
+
187
+
188
+
189
+ '分割した各項目を作業用シートに配置
190
+
191
+ Range(Cells(lRow, 1), Cells(lRow, UBound(strSplit) + 1)) = strSplit
192
+
193
+
194
+
195
+ '先頭行の場合、列数を保管
196
+
197
+ If lRow = 1 Then
198
+
199
+ lColMax = UBound(strSplit) + 1
200
+
201
+ End If
202
+
203
+ Loop
204
+
205
+
206
+
207
+ Close #iFree
208
+
209
+
210
+
211
+ lRowMax = lRow
212
+
213
+
214
+
215
+ 'EXCEL機能でソート
216
+
217
+ If lRowMax > 0 Then
218
+
219
+ 'ソート(見出し行は含めず、2行目からソート)
220
+
221
+ wsWorkSheet.Range(Cells(W_ROWS.DataStart, 1), Cells(lRowMax, lColMax)) _
222
+
223
+ .Sort Key1:=wsWorkSheet.Cells(W_ROWS.DataStart, W_COLS.Name), order1:=xlAscending, _
224
+
225
+ Key2:=wsWorkSheet.Cells(W_ROWS.DataStart, W_COLS.Kubun), order2:=xlAscending
226
+
227
+ End If
228
+
229
+ ```
230
+
231
+
232
+
233
+ ②レイアウト変更は①でソートした結果行を1行ずつ読み、1つ前の行と比較して前日cの判定を行いながら目的の形になるようセルに配置します。
234
+
235
+  (前日c判定はexcel関数でもできそうですが、今回はVBAでの質問のためVBA内で判定しています。)
236
+
237
+ ```
238
+
239
+ '--②レイアウト変更--
240
+
241
+ wsOutputSheet = WorkSheets("Sheet2")
242
+
243
+ wsOutputSheet.Activate
244
+
245
+
246
+
247
+ lWRow = 0
248
+
249
+ lWRowCnt = 0
250
+
251
+ strKEY = ""
252
+
253
+ strC = "×"
254
+
255
+
256
+
257
+ With wsOutputSheet
258
+
259
+ '見出し作成
260
+
261
+ lWRow = 1
262
+
263
+ lWRowCnt = 1
264
+
265
+ Range(Cells(lWRow, 1), Cells(lWRow, O_COLS.LAST)) = Split("名称,日付,前回c有無,a,b",",")
266
+
267
+
268
+
269
+ '作業用シートのデータ行をループ
270
+
271
+ For lRRow = W_ROWS.DataStart To lRowMax
272
+
273
+ 'ブレイク判定
274
+
275
+ If strKEY <> wsWorkSheet.Cells(lRRow, W_COLS.Name) Then
276
+
277
+ '前行までと人が変わっていたら・・・
278
+
279
+ lWRow = lWRow + lWRowCnt '新しい人の開始行
280
+
281
+ lWRowCnt = lColMax - W_COLS.DateSart + 1 '新しい人の出力行数(日数)
282
+
283
+
284
+
285
+ strC = "×" '前回cを初期化 ⇒"×"
286
+
287
+
288
+
289
+ '作業シートの日付列をループ処理
290
+
291
+ For lRCol = W_COLS.DateSart To lColMax
292
+
293
+ '新しい人の名称・日付・前回c(初期値)を出力
294
+
295
+
296
+
297
+ Next
298
+
299
+ End If
300
+
301
+
302
+
303
+ '作業用シートの日付列をループ
304
+
305
+ For lRCol = W_COLS.DateSart To lColMax
306
+
307
+ '識別種類で出力先を分岐
308
+
309
+ Select Case wsWorkSheet.Cells(lRRow, W_COLS.Kubun)
310
+
311
+ ' aの場合:aの列(O_COLS.TIME_A)に時間を出力
312
+
313
+ ' bの場合:bの列(O_COLS.TIME_B)に時間を出力
314
+
315
+ ' cの場合:cの列(O_COLS.C)に前回c判定を出力
316
+
317
+ ' その後、次行でセットする前回Cを準備 ⇒ 今回行に値があれば"○"、なければ"×"
318
+
319
+ End Select
320
+
321
+ Next
322
+
323
+ Next
324
+
325
+ End With
326
+
327
+ ```
328
+
329
+
330
+
331
+ 長くなってしまったため一部簡略化していますが頑張ってみてください。