配列操作用COM
vb/vbs配列操作用のCOMを作ってみました。 H24/3/27更新
簡単にいうとデータベースやExcel不要でソートが行えます。
※Excelは扱えるデータ件数に限界があります
三次元までのREDIM(再定義)と各種ソート(並べ替え)、GetDim(次元数取得)。
サンプルを見れば誰でも簡単に使えると思います。
REDIM(再定義)は通常は無理な左側の1・2次元目の数も増やせます。
SORT(並べ替え)は元の配列を変更しない仮想ソート(結果のインデックスだけ返す)と
実際に元の配列の並べ替えを実行するメソッドの両方があります。
すべてstd::stable_sortを使用、縦横ソートメソッド全12個。
複数条件対応の2個はSQL文の”ORDER BY 列1 ASC, 列2 DESC ...”相当。
標準ライブラリー使用なのでVB内でソートするよりはたぶん早いと思います。
次元数取得はVB系に実現コードはあるけど機能が無いのでつけました。
他はヘルパー用に次元や項目の入れ換え、UUID生成メソッド。
実用件数はセレロンCPU機で数万~数十万件、またはメモリと時間の限界まで。
動作環境はx86CPU(32/64)のWin98~Win8まですべて。
以下はSORTの使用方法のサンプルVBSです。メソッド発行は1行で済みますがテスト用データセットが長いです・・・
''説明文・・・仕様、メソッド・・・長いのでここでは省略 Option Explicit Dim MyObject, Ret, ColumnIndex, RowIndex Dim MyDim1, MyDim2, MyDim3, MyDim4(4,3), MyDim5(3,2,4), MyDim6(10,10,0) Dim MyDimX() Set MyObject = WScript.CreateObject("Variant.SafeArray") '' 1次元ソート MyDim1 = Array(33, 99, 111, 11, 66) WScript.Echo "Sort1(1) : " & MyObject.cSort1(MyDim1) WScript.Echo "並べ替えの結果、以下の順になります" SortResultOut1 MyDim1 WScript.Echo MyDim2 = Array("AaAaA", "AAAAA", "aaAAA", "aaaaa", "AaaaA", "aAAAa", "AAaaa") WScript.Echo "Sort1(2) : " & MyObject.cSort1(MyDim2) WScript.Echo "並べ替えの結果、以下の順になります" SortResultOut1 MyDim2 WScript.Echo MyDim3 = Array("AbAbA", "AAAAA", "bbAAA", "bbbbb", "AbbbA", "bAAAb", "AAbbb") WScript.Echo "Sort1(3) : " & MyObject.cSort1(MyDim3, "1") WScript.Echo "並べ替えの結果、以下の順になります" SortResultOut1 MyDim3 WScript.Echo '' 2次元ソート MyDim4(0,0) = "名字A名前A" MyDim4(0,1) = "〒376-0021" MyDim4(0,2) = CCur("\300000.45") MyDim4(0,3) = CDate("1989/10/28 10:30") MyDim4(1,0) = "名字B名前b" MyDim4(1,1) = "〒020-1000" MyDim4(1,2) = CCur("\223000.0") MyDim4(1,3) = CDate("1953/2/11 15:30") MyDim4(2,0) = "名字C名前C" MyDim4(2,1) = "〒105-1201" MyDim4(2,2) = CCur("\520000.8") MyDim4(2,3) = CDate("2002/4/7 4:30") MyDim4(3,0) = "名字A名前A" MyDim4(3,1) = "〒510-2641" MyDim4(3,2) = CCur("\170000.2") MyDim4(3,3) = CDate("1999/5/19 8:30") MyDim4(4,0) = "名字A名前B" MyDim4(4,1) = "〒188-0030" MyDim4(4,2) = CCur("\840000.99") MyDim4(4,3) = CDate("1920/7/22 12:30") ColumnIndex = 3 WScript.Echo "Sort2(4) : " & MyObject.cSort2(MyDim4, ColumnIndex) WScript.Echo "カラム" & ColumnIndex & "番目での並べ替えの結果、以下の順になります" SortResultOut2 MyDim4 WScript.Echo ColumnIndex = 1 WScript.Echo "Sort2(5) : " & MyObject.cSort2(MyDim4, ColumnIndex, "11111") WScript.Echo "カラム" & ColumnIndex & "番目での並べ替えの結果、以下の順になります" SortResultOut2 MyDim4 WScript.Echo ''2次元配列の行列入れ換え:元の配列がカラム(列)でのソートに適さない場合 ''カラムが人名で行が付帯情報の場合 ReDim MyDimX(4,3) MyDimX(0,0) = "氏名ZZZ" MyDimX(0,1) = "氏名FFF" MyDimX(0,2) = "氏名BBB" MyDimX(0,3) = "氏名PPP" MyDimX(1,0) = "1990/02/02 02:02:02" MyDimX(1,1) = "1990/01/01 01:01:01" MyDimX(1,2) = "1990/12/12 12:12:12" MyDimX(1,3) = "1990/03/03 03:03:03" MyDimX(2,0) = "〒888-8888" MyDimX(2,1) = "〒999-9999" MyDimX(2,2) = "〒111-1111" MyDimX(2,3) = "〒222-2222" MyDimX(3,0) = "点222" MyDimX(3,1) = "点111" MyDimX(3,2) = "点999" MyDimX(3,3) = "点333" MyDimX(4,0) = "戦闘力0,030,000" ''項目が文字型なのでソート用に桁を揃えている MyDimX(4,1) = "戦闘力0,200,000" MyDimX(4,2) = "戦闘力0,000,666" MyDimX(4,3) = "戦闘力0,000,010" WScript.Echo "Change2(1) : " & MyObject.Change2(MyDimX) ColumnIndex = 4 ''入れ換え後のカラム番号になっているので注意(戦闘力) WScript.Echo "Sort2(9) : " & MyObject.cSort2(MyDimX, ColumnIndex) WScript.Echo "行列を入れ換えてソートした結果" SortResultOut2 MyDimX ''元の行列表現にしたい場合は以下のコメントを外し再度入れ換える ''WScript.Echo "Change2(2) : " & MyObject.Change2(MyDimX) ''WScript.Echo "一旦行列を入れ換えてソートして行列を再入れ換えで戻した結果" ''SortResultOut2 MyDimX WScript.Echo '' 3次元ソート MyDim5(0,0,0) = 31 MyDim5(0,1,0) = 32 MyDim5(0,2,0) = CLng(76543) MyDim5(1,0,0) = 34 MyDim5(1,1,0) = 35 MyDim5(1,2,0) = 36 MyDim5(2,0,0) = 37 MyDim5(2,1,0) = 38 MyDim5(2,2,0) = 39 MyDim5(3,0,0) = 311 MyDim5(3,1,0) = 321 MyDim5(3,2,0) = 333 MyDim5(0,0,1) = 11 MyDim5(0,1,1) = 12 MyDim5(0,2,1) = CLng(98765) MyDim5(1,0,1) = 14 MyDim5(1,1,1) = 15 MyDim5(1,2,1) = 16 MyDim5(2,0,1) = 17 MyDim5(2,1,1) = 18 MyDim5(2,2,1) = 19 MyDim5(3,0,1) = 111 MyDim5(3,1,1) = 121 MyDim5(3,2,1) = 133 MyDim5(0,0,2) = 81 MyDim5(0,1,2) = 82 MyDim5(0,2,2) = CLng(23456) MyDim5(1,0,2) = 84 MyDim5(1,1,2) = 85 MyDim5(1,2,2) = 86 MyDim5(2,0,2) = 87 MyDim5(2,1,2) = 88 MyDim5(2,2,2) = 89 MyDim5(3,0,2) = 811 MyDim5(3,1,2) = 821 MyDim5(3,2,2) = 833 MyDim5(0,0,3) = 51 MyDim5(0,1,3) = 52 MyDim5(0,2,3) = CLng(34567) MyDim5(1,0,3) = 54 MyDim5(1,1,3) = 55 MyDim5(1,2,3) = 56 MyDim5(2,0,3) = 57 MyDim5(2,1,3) = 58 MyDim5(2,2,3) = 59 MyDim5(3,0,3) = 511 MyDim5(3,1,3) = 521 MyDim5(3,2,3) = 533 MyDim5(0,0,4) = 61 MyDim5(0,1,4) = 62 MyDim5(0,2,4) = CLng(12345) MyDim5(1,0,4) = 64 MyDim5(1,1,4) = 65 MyDim5(1,2,4) = 66 MyDim5(2,0,4) = 67 MyDim5(2,1,4) = 68 MyDim5(2,2,4) = 69 MyDim5(3,0,4) = 611 MyDim5(3,1,4) = 621 MyDim5(3,2,4) = 633 RowIndex = 0 ColumnIndex = 2 WScript.Echo "Sort3(6) : " & MyObject.cSort3(MyDim5, RowIndex, ColumnIndex) WScript.Echo "行列" & RowIndex & ":" & ColumnIndex & "位置での並べ替えの結果、以下の順になります" SortResultOut3 MyDim5 WScript.Echo RowIndex = 0 ColumnIndex = 0 WScript.Echo "Sort3(7) : " & MyObject.cSort3(MyDim6, RowIndex, ColumnIndex) WScript.Echo "行列" & RowIndex & ":" & ColumnIndex & "位置での並べ替えの結果、以下の順になります" SortResultOut3 MyDim6 WScript.Echo If 0 <> Err.Number Then WScript.Echo "VBScript Error: " & Err.Source & "/" & Err.Number & "/" & Err.Description End If WScript.Quit(Err.Number) ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '' 内容表示 ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Sub SortResultOut1(OrgArray) If False = IsArray(OrgArray) Then WScript.Echo "Exit Sub": Exit Sub End If Dim idx1 For idx1 = LBound(OrgArray, 1) To UBound(OrgArray, 1) WScript.Echo "順位" & idx1 & " " & OrgArray(idx1) Next End Sub Sub SortResultOut2(OrgArray) If False = IsArray(OrgArray) Then WScript.Echo "Exit Sub": Exit Sub End If Dim idx1, idx2, Val For idx1 = LBound(OrgArray, 1) To UBound(OrgArray, 1) WScript.Echo "------------------------- 順位" & idx1 For idx2 = LBound(OrgArray, 2) To UBound(OrgArray, 2) Val = OrgArray(idx1, idx2) If vbDate = VarType(Val) Then WScript.Echo FormatDateTime(Val,vbLongDate) & " " & FormatDateTime(Val,vbShortTime) ElseIf vbCurrency = VarType(Val) Then WScript.Echo FormatCurrency(Val) Else WScript.Echo Val End If Next Next End Sub Sub SortResultOut3(OrgArray) If False = IsArray(OrgArray) Then WScript.Echo "Exit Sub": Exit Sub End If ''テストデータが三次元目を区切りにした頁概念なのでidx3から回して表現してます Dim idx1, idx2, idx3, Val For idx3 = LBound(OrgArray, 3) To UBound(OrgArray, 3) WScript.Echo "------------------------- 順位" & idx3 For idx1 = LBound(OrgArray, 1) To UBound(OrgArray, 1) Val = "" For idx2 = LBound(OrgArray, 2) To UBound(OrgArray, 2) ''最後のテスト"Sort3(7)"は配列の中身が無いのでスキップ判定 If False = IsEmpty(OrgArray(idx1, idx2, idx3)) Then Val = Val & OrgArray(idx1, idx2, idx3) & "," & vbTab End If Next If 0 < Len(Val) Then WScript.Echo Val End If Next Next End Sub '''''''''''''''''''''''''''''''''''''''''''''''' 実行結果 '''''''''''''''''''''''''''''''''''''''' Sort1(1) : 0 並べ替えの結果、以下の順になります 順位0 11 順位1 33 順位2 66 順位3 99 順位4 111 Sort1(2) : 0 並べ替えの結果、以下の順になります 順位0 aaaaa 順位1 aaAAA 順位2 aAAAa 順位3 AaaaA 順位4 AaAaA 順位5 AAaaa 順位6 AAAAA Sort1(3) : 0 並べ替えの結果、以下の順になります 順位0 AAAAA 順位1 AAbbb 順位2 AbAbA 順位3 AbbbA 順位4 bAAAb 順位5 bbAAA 順位6 bbbbb Sort2(4) : 0 カラム3番目での並べ替えの結果、以下の順になります ------------------------- 順位0 名字A名前B 〒188-0030 \840,001 大正 9年7月22日 木曜日 12:30 ------------------------- 順位1 名字B名前b 〒020-1000 \223,000 昭和 28年2月11日 水曜日 15:30 ------------------------- 順位2 名字A名前A 〒376-0021 \300,000 平成 1年10月28日 土曜日 10:30 ------------------------- 順位3 名字A名前A 〒510-2641 \170,000 平成 11年5月19日 水曜日 08:30 ------------------------- 順位4 名字C名前C 〒105-1201 \520,001 平成 14年4月7日 日曜日 04:30 Sort2(5) : 0 カラム1番目での並べ替えの結果、以下の順になります ------------------------- 順位0 名字B名前b 〒020-1000 \223,000 昭和 28年2月11日 水曜日 15:30 ------------------------- 順位1 名字C名前C 〒105-1201 \520,001 平成 14年4月7日 日曜日 04:30 ------------------------- 順位2 名字A名前B 〒188-0030 \840,001 大正 9年7月22日 木曜日 12:30 ------------------------- 順位3 名字A名前A 〒376-0021 \300,000 平成 1年10月28日 土曜日 10:30 ------------------------- 順位4 名字A名前A 〒510-2641 \170,000 平成 11年5月19日 水曜日 08:30 Change2(1) : 0 Sort2(9) : 0 行列を入れ換えてソートした結果 ------------------------- 順位0 氏名PPP 1990/03/03 03:03:03 〒222-2222 点333 戦闘力0,000,010 ------------------------- 順位1 氏名BBB 1990/12/12 12:12:12 〒111-1111 点999 戦闘力0,000,666 ------------------------- 順位2 氏名ZZZ 1990/02/02 02:02:02 〒888-8888 点222 戦闘力0,030,000 ------------------------- 順位3 氏名FFF 1990/01/01 01:01:01 〒999-9999 点111 戦闘力0,200,000 Sort3(6) : 0 行列0:2位置での並べ替えの結果、以下の順になります ------------------------- 順位0 61, 62, 12345, 64, 65, 66, 67, 68, 69, 611, 621, 633, ------------------------- 順位1 81, 82, 23456, 84, 85, 86, 87, 88, 89, 811, 821, 833, ------------------------- 順位2 51, 52, 34567, 54, 55, 56, 57, 58, 59, 511, 521, 533, ------------------------- 順位3 31, 32, 76543, 34, 35, 36, 37, 38, 39, 311, 321, 333, ------------------------- 順位4 11, 12, 98765, 14, 15, 16, 17, 18, 19, 111, 121, 133, Sort3(7) : 0 行列0:0位置での並べ替えの結果、以下の順になります ------------------------- 順位0
コメントする
0件のコメント