SAK 図書館
VB テクニック編33 - シーケンシャルマッチング、シーケンシャルマージ処理
■SAK 関数利用規程 ・テクニック編で紹介する関数は、私こと Y.SAK の開発関数である。 ・著作権明示部分の改編は認めない。 ・個人、企業がこれらの関数を使用したり、一部を使用して新たなシステムや プログラムを開発することは自由です。 ・但し、これらの関数を一部でも使用しているソフトウェアをシェアウェア、 その他有償プロダクトとして配布・販売するには、私の許可が必要です。 (無償のフリーソフトウェアなら、自由に配布しても良い。) ・これらの関数を使用して発生した、いかなる形での損害も私こと Y.SAK は 賠償しません。 ■シーケンシャルマッチング、シーケンシャルマージ処理 ・二つの DB テーブル、二つの CSV ファイル、DB テーブルと CSV ファイル などのシーケンシャルマッチングやシーケンシャルマージは、次のように 処理する。(DB テーブルマッチング、DB テーブルマージ処理) ・シーケンシャルマッチングは二つのファイルの件数が大量にある場合に効果 を発揮する。(ランダム参照マッチングより超高速となる。) 以下の例では、DB テーブルと CSV ファイルのレコードをマッチングして いるが、どちらかのリードロジックを他方に適用すれば、DB テーブル同士、 または、CSV ファイル同士のマッチング処理が可能となる。 DB は ADO でコードしているが、oo4o でも似た感じである。 ・マッチングする二つのファイルのレコード順は、マッチングキーの順に ソートされていなければならない。マッチングキー順に並んでいない CSV ファイルの場合、ファイルソートロジックも必要になる。 (手っ取り早く、DB テーブルにセットアップしても良いが。) ・マッチングキーは、処理判定の簡素化のため、文字列に変換してセットする。 得意先CD が数値の場合は、mk2.tkcd = format(rec(3), "0000") のように 桁揃えもすること。 以下の例では、3 つの項目をマッチングキーとしているが、受注m の場合、 実は受注番号でユニークとなるので、マッチングキーはひとつで良い。 見本と言う意味で意味のない複数キーマッチを行っている。 また、AT END 時のマッチングキーには最大キーとなるデータをセットする。 この例では、chr(255) をセットしている。(半角の最大コード) ・CSV ファイルには見出し行はないものとして処理している。 ・イニシャルリードフラグ rsnx は、DB がオープンと同時に 1 件目読まれる ので、その制御を行っている。 ・実際のマッチング処理は、「'** マッチング or マージ」の '共にレコードにあるときの処理 'DB レコードが CSV レコードにないときの処理 'CSV レコードが DB レコードにないときの処理 に記述する。 ここにどのようなコードを書くかで、レコードマージになったり、マッチン グレコード抽出になったりする。 この三つの判定は、一致する条件が多いものを上に持ってくる方が処理は 速くなる。(微々たる速度差かもしれないが。) ・サンプルなのでエラー処理は行っていない。 Private Sub Command1_Click() Dim s3cn_ado As Variant Dim rs As Variant Dim fno As Integer Dim ct As Integer Dim i As Integer Dim mk1 As MATCH_KEY Dim mk2 As MATCH_KEY Dim mk1s As String Dim mk2s As String Dim rsnx As Boolean '** ODBC 接続 Set s3cn_ado = CreateObject("ADODB.Connection") s3cn_ado.Open "dsn=SAK3_ADO;uid=SAK;pwd=SAK" s3cn_ado.CursorLocation = 2 'adUseServer = 2 '** レコードセットオープン Set rs = s3cn_ado.Execute("select * from 受注m " _ & " order by 受注番号, 得意先CD, 品番") '** CSV 項目数取得 ct = GetCntCSV("infile.csv") If ct < 1 Then MsgBox "エラー" End End If ct = ct - 1 '添字を rs と同じ開始 0 にする ReDim rec(ct) As String '** ファイルオープン fno = FreeFile Open "infile.csv" For Input As fno Len = 32000 '** イニシャルリードフラグセット rsnx = False '** DB イニシャルリード mk1s = NextReadMk1(rsnx, rs, fno, ct, rec(), mk1, mk2) '** CSV イニシャルリード mk2s = NextReadMk2(rsnx, rs, fno, ct, rec(), mk1, mk2) '** イニシャルリードフラグセット rsnx = True '** マッチング or マージ Do Until rs.EOF And EOF(fno) Select Case True Case mk1s = mk2s '共にレコードにあるときの処理 print "mk1s = mk2s - " & mk1s & " - " & mk2s '... '次のマッチリード mk1s = NextReadMk1(rsnx, rs, fno, ct, rec(), mk1, mk2) mk2s = NextReadMk2(rsnx, rs, fno, ct, rec(), mk1, mk2) Case mk1s < mk2s 'DB レコードが CSV レコードにないときの処理 print "mk1s < mk2s - " & mk1s & " - " & mk2s '... '次のマッチリード mk1s = NextReadMk1(rsnx, rs, fno, ct, rec(), mk1, mk2) Case mk1s > mk2s 'CSV レコードが DB レコードにないときの処理 print "mk1s > mk2s - " & mk1s & " - " & mk2s '... '次のマッチリード mk2s = NextReadMk2(rsnx, rs, fno, ct, rec(), mk1, mk2) End Select Loop '** ファイルクローズ Close fno '** レコードセットクローズ rs.Close '** ODBC 接続解除 s3cn_ado.Close '** 処理終了 MsgBox "処理終了" End Sub '** マッチングキーパターン(標準モジュールで定義) Type MATCH_KEY jcno As String * 10 tkcd As String * 4 prno As String * 16 End Type Public Function NextReadMk1(rsnx As Boolean, rs As Variant, fno As Integer, ct As Integer, rec() As String, mk1 As MATCH_KEY, mk2 As MATCH_KEY) As String '** 次のレコードを読む If rsnx Then rs.movenext '** マッチングキーセット If rs.EOF Then mk1.jcno = String(10, chr(255)) mk1.tkcd = String(4 , chr(255)) mk1.prno = String(16, chr(255)) Else mk1.jcno = rs("受注番号") mk1.tkcd = rs("得意先CD") mk1.prno = rs("品番") End If '** 正常終了セット NextReadMk1 = mk1.jcno & mk1.tkcd & mk1.prno End Function Public Function NextReadMk2(rsnx As Boolean, rs As Variant, fno As Integer, ct As Integer, rec() As String, mk1 As MATCH_KEY, mk2 As MATCH_KEY) As String Dim i As Integer '** マッチングキーセット If EOF(fno) Then mk2.jcno = String(10, chr(255)) mk2.tkcd = String(4 , chr(255)) mk2.prno = String(16, chr(255)) Else '** 次のレコードを読む For i = 0 To ct Input #fno, rec(i) Next mk2.jcno = rec(0) mk2.tkcd = rec(3) mk2.prno = rec(1) End If '** 正常終了セット NextReadMk2 = mk2.jcno & mk2.tkcd & mk2.prno End Function ■VB テクニック編資料
■VB 入門編資料
■VB 基礎編資料
■VB ビジュアル編資料