一括表示

idx_search 投稿者:JA2BQX 太田 

こんにちは。 何時もお世話になります。

VB2010にて日付けを指定してレコード番号を取得しようとしています。
ソースの一部抜粋が下記です。

Declare Function MakeIndex Lib "Hamlog50.dll" (ByVal s As String, ByVal k As String, ByVal i As String) As int32
Declare Function idx_open Lib "Hamlog50.dll" (ByVal s As String, ByRef p As TIDXh) As Int32
Declare Sub idx_close Lib "Hamlog50.dll" (ByRef p As TIDXh)
Declare Function idx_search Lib "Hamlog50.dll" (ByRef p As TIDXh, ByVal s As String, ByVal l As Int32) As Int32

MakeIndex(hamlogpath, "DATE", "C:\Hamlog\Date.Ndx")
Ret = idx_open("C:\Hamlog\Date.Ndx", THindx)
search_date = "15/02/03"
rec_no_1st = idx_search(THindx, search_date, 8)
Call idx_close(THindx)


idx_search 関数の使い方ですが下記の ? には幾つを指定すれば良いでしょうか?
rec_no_1st = idx_search(THindx, search_date, ?)

Th524ap の Hamlog50.txt にて下記の様に記載されている len です。
search_date = "15/02/03" なら 8 で良いと思いますが、今は山シャックなのでテスト出来ない...。

コールサインの時には ゼロ で上手くサーチ出来ましたが。
 
MakeIndex(hamlogpath, "TIME", "C:\Hamlog\Time.Ndx") の時には
"12:34U" なら 6 で良いでしょうか。



引 数:idx
dBASE互換インデックスファイルの構造体

key
検索するキー。THW_seek()と同様。

len
検索するキーの長さを指定する。コールサインの文字列が全部一致するキーを検索する場合は6。


プリフィックスだけ一致の場合は3。ゼロの場合は、key が通常のヌルターミネート文字列であるとして検索する
 

2015/02/07(Sat) 13:53:27  [No.656]


Re: idx_search 投稿者:JG1MOU浜田 

> idx_search 関数の使い方ですが下記の ? には幾つを指定すれば良いでしょうか?
> rec_no_1st = idx_search(THindx, search_date, ?)

ゼロで大丈夫なはずですよ。
ゼロを指定すれば、内部で Length(search_date) でサーチします。

2015/02/07(Sat) 16:03:36  [No.657]


Re: idx_search 投稿者:JA2BQX 太田 

浜田さん、こんにちは。
早速の返信ありがとうございました。

> ゼロで大丈夫なはずですよ。
> ゼロを指定すれば、内部で Length(search_date) でサーチします。

分かりました。自宅に戻ったらテストして見ます。
今は山シャックでK1Nの追っかけ中です。
JAからは中央アメリカ、カリブは遠い....。

2015/02/07(Sat) 16:32:52  [No.658]


Re: idx_search 投稿者:JA2BQX 太田 

おはようございます。
試しているのですが , DATE と DATE+TIME のレコード番号が取れません。
CALLS と CODE は上手く取れるのですが、先に提示したコードでの
search_date には search_date = "01/02/03" 形式で良いでしょうか?

2015/02/08(Sun) 07:52:07  [No.659]


Re: idx_search 投稿者:JA2BQX 太田 

こんにちは。

バイナリー・エディターで中身を見ると
Hamlog.hdb と Date.Ndx との1レコード目の Date の16進数は
同じなのですが、検索キーの指定がまずいのかな?
何か事前処理が必要とも思えないのですが、悩んでいます...Hi。

VBユーザーでどなたか同じ処理をして経験がありますか?

2015/02/08(Sun) 08:19:02  [No.660]


Re: idx_search 投稿者:JG1MOU浜田 

> search_date には search_date = "01/02/03" 形式で良いでしょうか?

日付は数値で4バイト、時間は2バイトだったような・・・。
文字ではなく数値です。

search_date[0] = 20
search_date[1] = 1
search_date[2] = 2
search_date[3] = 3

2015/02/08(Sun) 08:33:17  [No.661]


Re: idx_search 投稿者:JA2BQX 太田 

浜田さん、ありがとうございます。 しかしまだ上手くいきません。

> > search_date には search_date = "01/02/03" 形式で良いでしょうか?
>
> 日付は数値で4バイト、時間は2バイトだったような・・・。
> 文字ではなく数値です。
> search_date[0] = 20
> search_date[1] = 1
> search_date[2] = 2
> search_date[3] = 3

Function MakeIndex(ByVal s As String, ByVal k As String, ByVal i As String) As Long を見ると
{"DATE", 4 } なので4バイトか...と思ってはいました。これはバイナリーになった時のバイト数ですね。

Function idx_search(p As TIDXh, ByVal s As String, ByVal l As Long) As Long
これを見るとキーは String ですが?

作成された Date.Ndx を見ると ヘッダー部が 520バイトかと。
データ部は1レコード当たり12バイトのように見えます。

レコード番号 : 4バイト 、日付 : 4バイト 、 ダミー: 4バイト


Date.Ndx のファイルサイズとレコード件数の帳尻が合わないみたいなので
データ構造の調べが間違えているように思っています。
出来ればデータ構造を教えていただけますか?

2015/02/08(Sun) 11:56:17  [No.664]


Re: idx_search 投稿者:JG1MOU浜田 

> Function idx_search(p As TIDXh, ByVal s As String, ByVal l As Long) As Long
> これを見るとキーは String ですが?

VBの場合はそのように宣言するしか思いつきませんでした。
C言語やPascalではchar型のポインタ、又はcharの配列です。


> Date.Ndx のファイルサイズとレコード件数の帳尻が合わないみたいなので
> データ構造の調べが間違えているように思っています。
> 出来ればデータ構造を教えていただけますか?

ファイルサイズとレコード件数は、釣り合わないはずです。
そんな単純な構造ではありません。
ですが、参考文献も処分してしまって・・・。
自分でもほとんど忘れてます。

データ構造を理解しなくても使えると思いますけど。

2015/02/08(Sun) 16:33:38  [No.666]


Re: idx_search 投稿者:JA2BQX 太田 

浜田さん、何回もありがとうございました。
下記のように修正したら目的のレコード番号が取得出来ました。

Dim search_date As String
Dim search_date_ary(4) As Byte

search_date_ary(0) = "20"
search_date_ary(1) = "15"
search_date_ary(2) = "01"
search_date_ary(3) = "05"

MakeIndex(hamlogpath, "DATE", "C:\thw2adi\Date.Ndx")
Ret = idx_open("C:\thw2adi\Date.Ndx", THindx)

search_date = System.Text.Encoding.GetEncoding(932).GetString(search_date_ary)

rec_no_1st = idx_search(THindx, search_date, 0)

Call idx_close(THindx)

2015/02/08(Sun) 18:16:29  [No.667]


Re: idx_search 投稿者:JG1MOU浜田 

> Dim search_date As String
> Dim search_date_ary(4) As Byte
>
> search_date_ary(0) = "20"
> search_date_ary(1) = "15"
> search_date_ary(2) = "01"
> search_date_ary(3) = "05"

バイト型の配列の1要素に、文字列?がコピーできてしまうのですか。

また、エンコードルーチンを呼び出す必要があるのですね。

いずれにしても、インデックスルーチンを使うと、検索がめちゃくちゃ
高速になります。

ハムログにおける、コールサインのサフィックス・サーチやワイルドカ
ード・サーチでは、HAMLOG.DX0からサーチしてますので20万件以上の
データから任意の100件くらいを探し出すのでも、瞬時に表示して
くれます。

2015/02/08(Sun) 22:53:51  [No.668]


Re: idx_search 投稿者:JA2BQX 太田 

こんにちは。

> バイト型の配列の1要素に、文字列?がコピーできてしまうのですか。

例の暗黙的変換?をしてくれているのかも、Hi。
str = "1200"
fp0 = Val(str.Substring(0, 2))
fp1 = Val(str.Substring(2, 2))
search_time_ary(0) = CByte(fp0)
search_time_ary(1) = CByte(fp1)
     ...とかが良いでしょうね、これで動きます。

1200 でサーチすると 12:00 J のレコード番号が求められます。
12:00 U のレコード番号を求めるにはどうしたらいいでしょうか?

Hamlog50.txt には 分の最上位ビットが1であればUTC とあります。
1000 0000 は 16進数で 80 なので10進数の128を加算して
12 と 128+0 をバイト配列に入れてテストしていますが間違いのようです。

どのように処理すれば良いのでしょうか?

2015/02/09(Mon) 07:50:01  [No.669]


Re: idx_search 投稿者:JG1MOU浜田 

> 1200 でサーチすると 12:00 J のレコード番号が求められます。
> 12:00 U のレコード番号を求めるにはどうしたらいいでしょうか?

分の数値 or &H80 です。
分 = 分 or &H80
論理和っていうのでしょうか。

逆に、最上位ビットをカットして分の値を取り出すには、
分の数値 and &H7F です。
分 = 分 and &H7F
論理積っていうのでしょうか。

2015/02/09(Mon) 20:28:13  [No.670]


Re: idx_search 投稿者:JA2BQX 太田 

こんばんは。浜田さん、ありがとうございます。
午前中から 同じようなことをしているのですが成功していませんでしたが
今、改めてテストしたら取得出来るようです....。

> 分の数値 or &H80 です。


Dim str As String = "1200"
fp0 = Val(str.Substring(0, 2))
fp1 = Val(str.Substring(2, 2))

search_time_ary(0) = CByte(fp0)

下記のどちらでOKです。
search_time_ary(1) = &H80 Or CByte(fp1)
search_time_ary(1) = CByte(128) Or CByte(fp1)

午前中のテストとコードは変わらないのですがテスト環境 (Hamlog.hdb) が間違えていたのかな....??

次の Date+Time のUTCも取れるようになりました。
的確なアドバイスを何時もありがとうございます。

2015/02/09(Mon) 22:07:21  [No.671]