いつもお世話になっております。ケロロです
今回mdbでテーブルの書き換えをしないといけなくなりまして
その作業中なのですがテーブルが増えすぎてきまして
自分なりにもうすこしスマートにできないかと思いまして
構造体配列の使用にいたりました。
この構造体中身は
・idno(文字型)
・rankupdate(日付型)
となっておりまして、まずrankupdate、idnoのソート順にしないといけません
がみようみまねで構造体配列を扱っておりましてrankupdate順にはならべられたのですが(もうひとつ構造体配列をもうけまして)
同日づけのidno順のソートがうまくいきません
過去ログに一件あったのですがわかりませんでしたし、ググッったりしても「構造体 配列 ソート」とかで調べてもそのものといのはなかったので
教えていただければと思います
またひとつの構造体配列だけでそんなものはできるといわれるかもしれないので
もしそんな方法があるのでしたら教え手いただけないでしょうか?
お願いします それでは
rankupdate + デリミタ + idno と言う文字列を作り、
構造体 -> ー次元文字列の配列 -> ソート -> 構造体に戻す
という具合にすれば簡単な様に思いますが。
オンメモリレコードセットに放り込んでソートするとか。
さっそくのお返事ありがとうございます
ねろさん>
自分はロジックにこだわりすぎてそんなことに考えつきませんでした
すみません
大変勉強になりました
Sayさん>
早急にごくの意味を調べます(汗)
今回自分にもすぐにできそうなので
ネロさんの案でやらせていただきます
それで回答もらってもうしわけないんですが
構造体配列の複数キーソートというのはのちのち必要になってくると思いますので
教えていただけたらと思うのですが
もちろんこれからはそういうのはつかうことはまずないというご指摘でしたら
肝に銘じてもおきたいので
よろしくお願いします
もともとVBには単純なソートの関数さえ存在しません。
ましてユーザー定義型となると。。。。
多次元配列のソート関数を自分で作るしか有りません。
ただしいくら頑張っても、VBで作るソートは遅いですよ。
なぜ文字列のソートを勧めたのかと言いますと、データーベースと言うことで
データーがかなり大きいと想像されたからです。
文字列にしてファイルに落としてしまえばDOSのSortコマンドが使えるからです。
たとえば下のコードは10万件のソートを、一瞬でやってしまいます。
Option Explicit
Private Type db
idno As String
rankupdate As Variant
End Type
Dim mdbdata(100000) As db
Private Sub Form_Load()
Dim i As Long
Dim File1 As String, File2 As String
Dim FileNo
'------テストデーターの作成--------------------------
For i = 0 To UBound(mdbdata) - 1
mdbdata(i).idno = Format(CStr(i), "0000000000") 'サンプルのデーター
mdbdata(i).rankupdate = Date + (i \ 10) 'サンプルのデーター
Next
'----------------------------------------------------
File1 = App.Path + "\" + "test1.txt" 'ソート前
File2 = App.Path + "\" + "test2.txt" 'ソート後
FileNo = FreeFile
Open File1 For Output As #FileNo
For i = 0 To UBound(mdbdata) - 1
Print #1, mdbdata(i).rankupdate & "," & mdbdata(i).idno 'データー結合
Next
Close
'ソート
Shell Environ("ComSpec") & " /c sort /r <" & Chr(34) _
& File1 & Chr(34) & " > " & Chr(34) & File2 & Chr(34)
End Sub
ご面倒おかけします。回答ありがとうございます。
追加での優先事項・追加項目がでてしまいまして
実装がすこし遅れがちになっております
結果がでしだいソース等のせますのでもうしばらくおまちください
会社環境でないとちょっと無理な感じで
というか自分でサンプルデータとかみようみまねでできないというのがなさけないですが
Sayさん>
けっこうオンメモリレコードセットの発言されてますね
調べ物したらお名前をなんどか拝見しましたし
これって構造体配列とオンメモリってどっちがはやいんでしょうね
ADOって仮装テーブルみたいなのつくれるんですね
DAOにはないのでしょうか探したらみあたらなかったもので(会社で作ってる分が以前からDAOのためどっちかというとDAOよりになっております)
おかげでまたひとつ語句をしりました
ねろさん>
mdbファイル自体は約300Mです。
でそのうちの会員用のテーブルが1万件
で昇格関係のプログラムなので
そういった昇格の系列みたいなものが3万件くらい
といった感じですが
実際昇格でソートが必要になる部分というのは将来かなり楽観的にみても40もないというのが現状です
その中のソートになるので特に心配はないかなっと思ってます
ただいろいろソートが複雑になりそうな気配はあります
たとえば今回の文字列にしても日付(降順)、会員番号(昇順)とかになるとやっぱりむずかしそうですし(単純に自分の脳みそがたりてない感はもちろんあります)
ということでロジックを勉強したいと思ったしだいであります
ここのログにも前にありましたけどそのログを読み解く力が自分にはなかったので
ソート関係の本を買ったら構造体配列の複数キーのやり方とかすこしはのってますかね
DOSの扱い方まで教え手いただきましてありがとうございます
自分にもうごかせて素人に近いものですから感動しています
このsortコマンドもっとなにかやれないかとかもちょっと調べてみます
それでは
遅くなってすみません
とりあえずこんな感じになっています
変な書き方ですみません
結局要望がひとつ追加になったので3つのフィールドをつなげてソートしました
配列追加分
ReDim Preserve idno_h(lp3)
idno_h(lp3).idno = rst.Fields("idno").Value
idno_h(lp3).rankupdate = DMax("rankupdate", "昇格履歴", "kairank = 2 and idno = " & "'" & rst.Fields("idno").Value & "'")
idno_h(lp3).rankup_rank = 3
idno_h(lp3).TreeType_sort = idno_h(lp3).rankup_rank & " " & CStr(idno_h(lp3).rankupdate) & " " & idno_h(lp3).idno
lp3 = lp3 + 1
ソート
For i3 = LBound(idno_h) To UBound(idno_h) - 1
For j3 = LBound(idno_h) To LBound(idno_h) + UBound(idno_h) - i3 - 1
If idno_h(j3).TreeType_sort > idno_h(j3 + 1).TreeType_sort Then
lvarBuf = idno_h(j3).idno
idno_h(j3).idno = idno_h(j3 + 1).idno
idno_h(j3 + 1).idno = lvarBuf
lvarBuf = idno_h(j3).rankup_rank
idno_h(j3).rankup_rank = idno_h(j3 + 1).rankup_rank
idno_h(j3 + 1).rankup_rank = lvarBuf
lvarBuf = idno_h(j3).rankupdate
idno_h(j3).rankupdate = idno_h(j3 + 1).rankupdate
idno_h(j3 + 1).rankupdate = lvarBuf
lvarBuf = idno_h(j3).TreeType_sort
idno_h(j3).TreeType_sort = idno_h(j3 + 1).TreeType_sort
idno_h(j3 + 1).TreeType_sort = lvarBuf
End If
Next j3
Next i3
すみません間違えました
ソート分
For i3 = LBound(idno_h) To UBound(idno_h) - 1
For j3 = LBound(idno_h) To LBound(idno_h) + UBound(idno_h) - i3 - 1
If idno_h(j3).TreeType_sort > idno_h(j3 + 1).TreeType_sort Then
lvarBuf = idno_h(j3).TreeType_sort
idno_h(j3).TreeType_sort = idno_h(j3 + 1).TreeType_sort
idno_h(j3 + 1).TreeType_sort = lvarBuf
End If
Next j3
Next i3
お返事くださった方どうもありがとうございました
まだまだ先は長そうですけど、この調子でがんばりたいと思います
ツイート | ![]() |