回答編集履歴

1

サンプルコードの修正

2015/11/05 11:58

投稿

pi-chan
pi-chan

スコア5936

test CHANGED
@@ -255,3 +255,307 @@
255
255
  End Sub
256
256
 
257
257
  ```
258
+
259
+
260
+
261
+ ---
262
+
263
+ <コード修正:2015/11/05 22:56>
264
+
265
+
266
+
267
+ お待たせ致しました。コードを修正致しましたので、再度ご確認頂けますか?
268
+
269
+ ```
270
+
271
+ Option Explicit
272
+
273
+
274
+
275
+
276
+
277
+
278
+
279
+ '------------------------------------------------------------------------------
280
+
281
+ ' 正規表現による文字列置換
282
+
283
+ '------------------------------------------------------------------------------
284
+
285
+ Function RegReplace(strTarget As String, _
286
+
287
+ strPattern As String, _
288
+
289
+ strReplaced As String, _
290
+
291
+ Optional blnGlobal As Boolean = False) As String
292
+
293
+
294
+
295
+ Dim objRex As Object
296
+
297
+
298
+
299
+ Set objRex = CreateObject("VBScript.RegExp")
300
+
301
+
302
+
303
+ objRex.Pattern = strPattern
304
+
305
+ objRex.Global = blnGlobal
306
+
307
+ RegReplace = objRex.Replace(strTarget, strReplaced)
308
+
309
+
310
+
311
+
312
+
313
+ Set objRex = Nothing
314
+
315
+
316
+
317
+ End Function
318
+
319
+
320
+
321
+
322
+
323
+
324
+
325
+ '------------------------------------------------------------------------------
326
+
327
+ ' 正規表現によるマッチング
328
+
329
+ '------------------------------------------------------------------------------
330
+
331
+ Function RegMatch(strTarget As String, _
332
+
333
+ strPattern As String) As Boolean
334
+
335
+
336
+
337
+ Dim objRex As Object
338
+
339
+
340
+
341
+ Set objRex = CreateObject("VBScript.RegExp")
342
+
343
+
344
+
345
+ objRex.Pattern = strPattern
346
+
347
+ RegMatch = objRex.Test(strTarget)
348
+
349
+
350
+
351
+
352
+
353
+ Set objRex = Nothing
354
+
355
+
356
+
357
+ End Function
358
+
359
+
360
+
361
+
362
+
363
+
364
+
365
+ '------------------------------------------------------------------------------
366
+
367
+ ' 対象データの並べ替え
368
+
369
+ '------------------------------------------------------------------------------
370
+
371
+ Sub CustomSort()
372
+
373
+
374
+
375
+ Dim xlBook As Workbook
376
+
377
+ Dim xlSheet As Worksheet
378
+
379
+ Dim vntTarget As Variant
380
+
381
+ Dim strOrder() As String
382
+
383
+ Dim o As Long
384
+
385
+ Dim i As Long
386
+
387
+ Dim j As Long
388
+
389
+ Dim k As Long
390
+
391
+ Dim l As Long
392
+
393
+
394
+
395
+ Set xlBook = ThisWorkbook
396
+
397
+ Set xlSheet = xlBook.Worksheets("Sheet1")
398
+
399
+
400
+
401
+ ' 文字列部の並び順の指定
402
+
403
+ i = 1
404
+
405
+ ReDim Preserve strOrder(i)
406
+
407
+ strOrder(i) = "Z"
408
+
409
+ '
410
+
411
+ i = i + 1
412
+
413
+ ReDim Preserve strOrder(i)
414
+
415
+ strOrder(i) = "WX"
416
+
417
+ '
418
+
419
+ i = i + 1
420
+
421
+ ReDim Preserve strOrder(i)
422
+
423
+ strOrder(i) = "ST"
424
+
425
+ '
426
+
427
+ i = i + 1
428
+
429
+ ReDim Preserve strOrder(i)
430
+
431
+ strOrder(i) = "UV"
432
+
433
+ '
434
+
435
+ i = i + 1
436
+
437
+ ReDim Preserve strOrder(i)
438
+
439
+ strOrder(i) = "Y"
440
+
441
+
442
+
443
+ ' ソート結果出力先の列番号
444
+
445
+ o = 1
446
+
447
+
448
+
449
+ With xlSheet
450
+
451
+ ' ソート対象の領域を配列に読み込み
452
+
453
+ vntTarget = .Range(.Cells(1, 1), .Cells(Rows.Count, 2).End(xlUp))
454
+
455
+
456
+
457
+ ' アルファベット部のソート順にブロック化した際の開始行と最終行の行番号を初期化
458
+
459
+ k = 1
460
+
461
+ l = 1
462
+
463
+
464
+
465
+ ' 文字列部の並び順に数値部の昇順にソートする
466
+
467
+ For i = 1 To 5
468
+
469
+ ' 文字列部の並び順にブロック化
470
+
471
+ For j = 1 To UBound(vntTarget, 1)
472
+
473
+ If RegMatch(CStr(vntTarget(j, 1)), "^" & strOrder(i) & "[0-9]") Then
474
+
475
+ .Cells(l, o).Value = CStr(vntTarget(j, 1))
476
+
477
+ .Cells(l, o + 1).Value = CStr(vntTarget(j, 2))
478
+
479
+ .Cells(l, o + 2).Value = RegReplace(CStr(vntTarget(j, 1)), "[A-Za-z]+", "", True)
480
+
481
+ l = l + 1
482
+
483
+ End If
484
+
485
+ Next j
486
+
487
+
488
+
489
+ ' ブロック毎に数値順にソート
490
+
491
+ .Range(.Cells(k, o), .Cells(l - 1, o + 2)).Sort _
492
+
493
+ key1:=.Cells(k, 3), _
494
+
495
+ Order1:=xlAscending, _
496
+
497
+ Header:=xlNo, _
498
+
499
+ OrderCustom:=1, _
500
+
501
+ MatchCase:=False, _
502
+
503
+ Orientation:=xlTopToBottom, _
504
+
505
+ SortMethod:=xlPinYin, _
506
+
507
+ DataOption1:=xlSortTextAsNumbers
508
+
509
+
510
+
511
+ ' ソート用に使用した数値列を削除
512
+
513
+ .Range(.Cells(k, o + 2), .Cells(l - 1, o + 2)).ClearContents
514
+
515
+ k = l
516
+
517
+ Next i
518
+
519
+ End With
520
+
521
+
522
+
523
+
524
+
525
+ Set xlSheet = Nothing
526
+
527
+ Set xlBook = Nothing
528
+
529
+
530
+
531
+ End Sub
532
+
533
+ ```
534
+
535
+
536
+
537
+ 改善点は2箇所です。
538
+
539
+
540
+
541
+ まず、ソートそのものに関する改善は下記1行のみです。
542
+
543
+ `If RegMatch(CStr(vntTarget(j, 1)), "^" & strOrder(i) & "[0-9]") Then`
544
+
545
+ ソートの基準になる「英字部分」のマッチングで、余計な文字列がマッチしてしまわぬよう「正規表現」を以下のように変更しました。
546
+
547
+ ```
548
+
549
+ 修正前)strOrder(i)
550
+
551
+ 修正後)"^" & strOrder(i) & "[0-9]" ← 文字列の「先頭」〜「最初の数字」までをマッチング
552
+
553
+ ```
554
+
555
+
556
+
557
+ もう一箇所はついで(本質的ではない)ですが、ソートの基準になる英文字部分の定義に「動的配列」を使用することで、追加や順序の入れ替えを楽に出来るようにしてみました。
558
+
559
+
560
+
561
+ 以上、ご参考になれば幸いです。