HOME 無線 PC−1245 MSX ファミコン 迷路
パソコン通信 売店 病院 PC−9800 PDA 太陽光発電 経済


JP3TLC's homepage
無線



「無線」メニュー

電子QSL(hQSL・eQSL)への対応

 標記の件、普段ハムログ等を使っていなくても、 QSLを発行する時だけ普段使っているログソフトからログデータを 出力・変換してハムログ等でインポートすれば、 問題なく電子QSLを発行できることが分かりました。 インポートするファイルはただのテキストファイルです。 CSV?ADIF?なんかややこしそうだからやめたやーめた、とか思ってましたがもっと早くやればよかった(笑)。 当方は約30年前のパソコン(PC−9821)を使用しているので QuickBASICで変換プログラムを作りましたが、 ウィンドウズのperlでも同じ動作をするプログラムが作成できると思います。 よかったら参考にされてみてください。

@当方の約35年前のログソフトから出力したデータ(抜粋)
07/19/2025,19:01,JH9OMQ,8,59 ,59 ,18  ,SSB,なかはら    ,北海道,釧路市        ,0106 , ,×,                                        
07/20/2025,16:58,JA7FVT, ,59 ,59 ,7   ,SSB,みうら      ,宮城  ,仙台市        ,0601 , ,サ,                                        
07/20/2025,18:04,JA6OTW, ,59 ,59 ,7   ,SSB,くの        ,佐賀  ,杵島郡        ,41003, ,ナ,                                        
07/20/2025,19:21,JQ1CAQ, ,59 ,59 ,7   ,SSB,こまつざき  ,茨城  ,石岡市        ,1405 , ,H,                                        
07/20/2025,19:27,JI3KKJ,2,59 ,59 ,7   ,SSB,とば        ,愛知  ,丹羽郡        ,20009, ,サ,A  おおぐちちょう                       
07/20/2025,19:34,JI4UMT, ,59 ,59 ,7   ,SSB,わだ        ,岡山  ,岡山市        ,3101 , ,×,                                        
07/20/2025,19:37,JF8FZR, ,59 ,59 ,7   ,SSB,こすぎ      ,北海道,岩見沢市      ,0110 , ,サ,IC7300 50W 18mh 水平DP                  
07/20/2025,19:43,JL4OND, ,59 ,59 ,7   ,SSB,こさか      ,岡山  ,高梁市        ,3111 , ,H,                                        
07/20/2025,19:46,JL7MRO, ,59 ,59 ,7   ,SSB,たけだ      ,宮城  ,仙台市        ,0601 , ,H,                                        
07/20/2025,19:49,JP2TWE, ,59 ,59 ,7   ,SSB,とおやま    ,愛知  ,名古屋市      ,2001 , ,H,                                        
07/20/2025,19:55,JA4CGP,4,59 ,59 ,7   ,SSB,のむら      ,山口  ,周南市        ,3315 , ,サ,PK183                                   
07/20/2025,19:59,JL7DHW, ,59 ,59 ,7   ,SSB,ふじしま    ,宮城  ,仙台市        ,0601 , ,サ,                                        
07/20/2025,20:12,JS2NWC, ,59 ,59 ,7   ,SSB,わけべ      ,愛知  ,春日井市      ,2007 , ,H,                                        
※交信日時順にソートした後、ファイル出力機能で作成しました。本当は何万行もありますが、ここでは以降どのように変換されるか見るのに必要な最後の部分だけ抜粋しています。当方使用のソフトでは普通のCSVファイルも出力可能でしたが、どうやら備考内に「,」(カンマ)が含まれたデータがあるらしく、変換したらずっこけたので桁を固定して桁の位置で何の項目か判別することにしています。

Aハムログでインポートするデータ
"JH9OMQ","25/07/19","19:01J","59","59","18","SSB","","","J","","","","","0"
"JA7FVT","25/07/20","16:58J","59","59","7","SSB","","","J","","","","","0"
"JA6OTW","25/07/20","18:04J","59","59","7","SSB","","","J","","","","","0"
"JQ1CAQ","25/07/20","19:21J","59","59","7","SSB","","","J","","","","","0"
"JI3KKJ","25/07/20","19:27J","59","59","7","SSB","","","J","","","","","0"
"JI4UMT","25/07/20","19:34J","59","59","7","SSB","","","J","","","","","0"
"JF8FZR","25/07/20","19:37J","59","59","7","SSB","","","J","","","","","0"
"JL4OND","25/07/20","19:43J","59","59","7","SSB","","","J","","","","","0"
"JL7MRO","25/07/20","19:46J","59","59","7","SSB","","","J","","","","","0"
"JP2TWE","25/07/20","19:49J","59","59","7","SSB","","","J","","","","","0"
"JA4CGP","25/07/20","19:55J","59","59","7","SSB","","","J","","","","","0"
"JL7DHW","25/07/20","19:59J","59","59","7","SSB","","","J","","","","","0"
"JS2NWC","25/07/20","20:12J","59","59","7","SSB","","","J","","","","","0"
※自分のログに7文字以上のコールがあったらそのデータは無視して飛ばしています。7文字以上のコールは記念局等と思われるのでカード発行をする必要はありません。モードの3項目後ろは無条件に「J」、最後に「0」を出力してますが、私が参考にしたサイトのお手本がそうなっていたのでそうしました。最後の「0」は何だかよく分かりませんが、「J」はQSLの送付方法のようです。HAMLOGで見たら最初QSL欄が「J」でこちらからhQSLを送信して成功したら「JH」に変わり、さらに先方からhQSLが届いたら「JHH」になるようです。つまり、本当は最初から一律「J」はおかしいのですが、HAMLOGはhQSLを送るためだけに使っていて、カードの管理は自分のログソフトを使うので、これで問題ありません。(おい)

B@からAを作成するBASICプログラム
PRINT "【HAMLOG用CSVファイル作成】"
REM 06/21/2025,16:38,JM8RTP,8,59 ,59 ,7   ,SSB,あいない    ,北海道,札幌市        ,0101 , ,サ,                                 
REM JP3ABC,25/06/22,10:44J,59,59,50,SSB,,,J,,,,,0

INPUT "入力ファイル名(省略時TEMP.TXT やめるQ):"; FILNAM$
IF FILNAM$ = "Q" OR FILNAM$ = "q" THEN END
INPUT "前回アップロード日(MM/DD/YYYY)JST(省略時は前回日付):"; ZENDATE$
INPUT "前回アップロード時間(HH:MM)JST(省略時は前回時刻):"; ZENTIME$
IF FILNAM$ = "" THEN FILNAM$ = "TEMP.TXT"
IF ZENDATE$ = "" OR ZENTIME$ = "" THEN
    OPEN "HAMLOG.CFG" FOR INPUT AS #3
    LINE INPUT #3, ADIBUF$
    ZENDATE$ = MID$(ADIBUF$, 6, 2) + "/" + RIGHT$(ADIBUF$, 2) + "/" + LEFT$(ADIBUF$, 4)
    LINE INPUT #3, ADIBUF$
    ZENTIME$ = LEFT$(ADIBUF$, 5)
    CLOSE #3
END IF
OPEN "HAMLOG.CFG" FOR OUTPUT AS #3
PRINT #3, DATE$
PRINT #3, TIME$
CLOSE #3

OPEN FILNAM$ FOR INPUT AS #1
IF INSTR(FILNAM$, ".") > 0 THEN
    OPEN LEFT$(FILNAM$, INSTR(FILNAM$, ".") - 1) + ".CSV" FOR OUTPUT AS #2
ELSE
    OPEN FILNAM$ + ".CSV" FOR OUTPUT AS #2
END IF

WHILE NOT EOF(1)
    LINE INPUT #1, BUF$

    QSODATE$ = LEFT$(BUF$, 10)
    IF RIGHT$(QSODATE$, 4) < RIGHT$(ZENDATE$, 4) THEN GOTO NXTDATA
    IF RIGHT$(QSODATE$, 4) = RIGHT$(ZENDATE$, 4) THEN
        IF LEFT$(QSODATE$, 5) < LEFT$(ZENDATE$, 5) THEN GOTO NXTDATA
    END IF
    QSOTIME$ = MID$(BUF$, 12, 5)
    IF QSOTIME$ = "     " THEN GOTO NXTDATA
    IF QSODATE$ = ZENDATE$ THEN
        IF QSOTIME$ < ZENTIME$ THEN GOTO NXTDATA
    END IF

    CALLSIGN$ = MID$(BUF$, 18, 6)
    WHILE RIGHT$(CALLSIGN$, 1) = " "
        CALLSIGN$ = LEFT$(CALLSIGN$, LEN(CALLSIGN$) - 1)
    WEND

    MOBILE$ = MID$(BUF$, 25, 1)
    IF MOBILE$ <> " " THEN
        IF MOBILE$ < "0" OR MOBILE$ > "9" THEN GOTO NXTDATA
    END IF

    UR$ = MID$(BUF$, 27, 3)
    IF UR$ = "   " THEN GOTO NXTDATA
    IF RIGHT$(UR$, 1) = " " THEN UR$ = LEFT$(UR$, LEN(UR$) - 1)

    MY$ = MID$(BUF$, 31, 3)
    IF MY$ = "   " THEN GOTO NXTDATA
    IF RIGHT$(MY$, 1) = " " THEN MY$ = LEFT$(MY$, LEN(MY$) - 1)

    FREQ$ = MID$(BUF$, 35, 4)
    WHILE RIGHT$(FREQ$, 1) = " "
        FREQ$ = LEFT$(FREQ$, LEN(FREQ$) - 1)
    WEND

    MODE$ = MID$(BUF$, 40, 3)
    IF RIGHT$(MODE$, 1) = " " THEN MODE$ = LEFT$(MODE$, LEN(MODE$) - 1)

    YEAR$ = RIGHT$(QSODATE$, 2)
    MONTH$ = LEFT$(QSODATE$, 2)
    DAY$ = MID$(QSODATE$, 4, 2)

    D$ = CHR$(34)
    DC$ = D$ + ","

    PRINT #2, D$ + CALLSIGN$ + DC$;
    PRINT #2, D$ + YEAR$ + "/" + MONTH$ + "/" + DAY$ + DC$;
    PRINT #2, D$ + QSOTIME$ + "J" + DC$;
    PRINT #2, D$ + UR$ + DC$;
    PRINT #2, D$ + MY$ + DC$;
    PRINT #2, D$ + FREQ$ + DC$;
    PRINT #2, D$ + MODE$ + DC$;
    PRINT #2, D$ + DC$;
    PRINT #2, D$ + DC$;
    PRINT #2, D$ + "J" + DC$;
    PRINT #2, D$ + DC$;
    PRINT #2, D$ + DC$;
    PRINT #2, D$ + DC$;
    PRINT #2, D$ + DC$;
    PRINT #2, D$ + "0" + D$

NXTDATA:
WEND

CLOSE #1
CLOSE #2
※ファイル名とか聞いてきますが、いつも通りでよければエンターキー空打ちで済むようにしています。頭から全件読み込んで対象外のデータは、はじいています。必要なデータは最後のほうだけなので、頭から読み込むのは無駄ですが、数万件あっても実用的な時間(十秒あまり)で処理が終わっています。(CPU:AMD K6U300MHz)

CeQSLにアップロードするADIF
<CALL:6>JH9OMQ<BAND:3>17M<MODE:3>SSB<QSO_DATE:8>20250719<TIME_ON:4>1001<RST_SENT:2>59<RST_RCVD:2>59<EOR>
<CALL:6>JA7FVT<BAND:3>40M<MODE:3>SSB<QSO_DATE:8>20250720<TIME_ON:4>0758<RST_SENT:2>59<RST_RCVD:2>59<EOR>
<CALL:6>JA6OTW<BAND:3>40M<MODE:3>SSB<QSO_DATE:8>20250720<TIME_ON:4>0904<RST_SENT:2>59<RST_RCVD:2>59<EOR>
<CALL:6>JQ1CAQ<BAND:3>40M<MODE:3>SSB<QSO_DATE:8>20250720<TIME_ON:4>1021<RST_SENT:2>59<RST_RCVD:2>59<EOR>
<CALL:6>JI3KKJ<BAND:3>40M<MODE:3>SSB<QSO_DATE:8>20250720<TIME_ON:4>1027<RST_SENT:2>59<RST_RCVD:2>59<EOR>
<CALL:6>JI4UMT<BAND:3>40M<MODE:3>SSB<QSO_DATE:8>20250720<TIME_ON:4>1034<RST_SENT:2>59<RST_RCVD:2>59<EOR>
<CALL:6>JF8FZR<BAND:3>40M<MODE:3>SSB<QSO_DATE:8>20250720<TIME_ON:4>1037<RST_SENT:2>59<RST_RCVD:2>59<EOR>
<CALL:6>JL4OND<BAND:3>40M<MODE:3>SSB<QSO_DATE:8>20250720<TIME_ON:4>1043<RST_SENT:2>59<RST_RCVD:2>59<EOR>
<CALL:6>JL7MRO<BAND:3>40M<MODE:3>SSB<QSO_DATE:8>20250720<TIME_ON:4>1046<RST_SENT:2>59<RST_RCVD:2>59<EOR>
<CALL:6>JP2TWE<BAND:3>40M<MODE:3>SSB<QSO_DATE:8>20250720<TIME_ON:4>1049<RST_SENT:2>59<RST_RCVD:2>59<EOR>
<CALL:6>JA4CGP<BAND:3>40M<MODE:3>SSB<QSO_DATE:8>20250720<TIME_ON:4>1055<RST_SENT:2>59<RST_RCVD:2>59<EOR>
<CALL:6>JL7DHW<BAND:3>40M<MODE:3>SSB<QSO_DATE:8>20250720<TIME_ON:4>1059<RST_SENT:2>59<RST_RCVD:2>59<EOR>
<CALL:6>JS2NWC<BAND:3>40M<MODE:3>SSB<QSO_DATE:8>20250720<TIME_ON:4>1112<RST_SENT:2>59<RST_RCVD:2>59<EOR>
※それぞれの山カッコ(不等号)内の数字は文字数を表しています。CWはモード2文字、レポートは3文字(599)など適宜変更してください。なお、バンドは波長表示です。時刻はUTCです。これらはADIFの規則にそう書かかれているので勝手にMHzやJSTで出力することはできません。

D@からCを作成するBASICプログラム
PRINT "【EQSLアップロード用ADIF作成】"
REM 06/21/2025,16:38,JM8RTP,8,59 ,59 ,7   ,SSB,あいない    ,北海道,札幌市        ,0101 , ,サ,                               
REM <CALL:6>JP3TLC<BAND:3>20M<MODE:4>RTTY<QSO_DATE:8>19960513<TIME_ON:4>1305<EOR>
INPUT "入力ファイル名(省略時TEMP.TXT やめるQ):"; FILNAM$
IF FILNAM$ = "Q" OR FILNAM$ = "q" THEN END
INPUT "前回アップロード日(MM/DD/YYYY)JST(省略時は前回日付):"; ZENDATE$
INPUT "前回アップロード時間(HH:MM)JST(省略時は前回時刻):"; ZENTIME$
IF FILNAM$ = "" THEN FILNAM$ = "TEMP.TXT"
IF ZENDATE$ = "" OR ZENTIME$ = "" THEN
    OPEN "ADIF.CFG" FOR INPUT AS #3
    LINE INPUT #3, ADIBUF$
    ZENDATE$ = MID$(ADIBUF$, 6, 2) + "/" + RIGHT$(ADIBUF$, 2) + "/" + LEFT$(ADIBUF$, 4)
    LINE INPUT #3, ADIBUF$
    ZENTIME$ = LEFT$(ADIBUF$, 5)
    CLOSE #3
END IF
OPEN "ADIF.CFG" FOR OUTPUT AS #3
PRINT #3, DATE$
PRINT #3, TIME$
CLOSE #3

OPEN FILNAM$ FOR INPUT AS #1
IF INSTR(FILNAM$, ".") > 0 THEN
    OPEN LEFT$(FILNAM$, INSTR(FILNAM$, ".") - 1) + ".ADI" FOR OUTPUT AS #2
ELSE
    OPEN FILNAM$ + ".ADI" FOR OUTPUT AS #2
END IF
WHILE NOT EOF(1)
    LINE INPUT #1, BUF$

    QSODATE$ = LEFT$(BUF$, 10)
    IF RIGHT$(QSODATE$, 4) < RIGHT$(ZENDATE$, 4) THEN GOTO NXTDATA
    IF RIGHT$(QSODATE$, 4) = RIGHT$(ZENDATE$, 4) THEN
        IF LEFT$(QSODATE$, 5) < LEFT$(ZENDATE$, 5) THEN GOTO NXTDATA
    END IF

    QSOTIME$ = MID$(BUF$, 12, 5)
    IF QSOTIME$ = "     " THEN GOTO NXTDATA
    IF QSODATE$ = ZENDATE$ THEN
        IF QSOTIME$ < ZENTIME$ THEN GOTO NXTDATA
    END IF

    CALLSIGN$ = MID$(BUF$, 18, 6)
    WHILE RIGHT$(CALLSIGN$, 1) = " "
        CALLSIGN$ = LEFT$(CALLSIGN$, LEN(CALLSIGN$) - 1)
    WEND

    MOBILE$ = MID$(BUF$, 25, 1)
    IF MOBILE$ <> " " THEN
        IF MOBILE$ < "0" OR MOBILE$ > "9" THEN GOTO NXTDATA
    END IF

    UR$ = MID$(BUF$, 27, 3)
    IF UR$ = "   " THEN GOTO NXTDATA
    IF RIGHT$(UR$, 1) = " " THEN UR$ = LEFT$(UR$, LEN(UR$) - 1)

    MY$ = MID$(BUF$, 31, 3)
    IF MY$ = "   " THEN GOTO NXTDATA
    IF RIGHT$(MY$, 1) = " " THEN MY$ = LEFT$(MY$, LEN(MY$) - 1)

    FREQ$ = MID$(BUF$, 35, 4)

    MODE$ = MID$(BUF$, 40, 3)
    IF RIGHT$(MODE$, 1) = " " THEN MODE$ = LEFT$(MODE$, LEN(MODE$) - 1)

    YEAR = VAL(RIGHT$(QSODATE$, 4))
    MONTH = VAL(LEFT$(QSODATE$, 2))
    DATE = VAL(MID$(QSODATE$, 4, 2))
    HOUR = VAL(LEFT$(QSOTIME$, 2))
    MIN = VAL(RIGHT$(QSOTIME$, 2))

    HOUR = HOUR - 9
    IF HOUR < 0 THEN
        HOUR = HOUR + 24
        DATE = DATE - 1
        IF DATE < 1 THEN
            MONTH = MONTH - 1
            IF MONTH < 1 THEN
                YEAR = YEAR - 1
                MONTH = 12
            END IF
            IF MONTH = 1 THEN DATE = 31
            IF MONTH = 2 AND (YEAR MOD 4 = 0) THEN DATE = 29
            IF MONTH = 2 AND (YEAR MOD 4 <> 0) THEN DATE = 28
            IF MONTH = 3 THEN DATE = 31
            IF MONTH = 4 THEN DATE = 30
            IF MONTH = 5 THEN DATE = 31
            IF MONTH = 6 THEN DATE = 30
            IF MONTH = 7 THEN DATE = 31
            IF MONTH = 8 THEN DATE = 31
            IF MONTH = 9 THEN DATE = 30
            IF MONTH = 10 THEN DATE = 31
            IF MONTH = 11 THEN DATE = 30
            IF MONTH = 12 THEN DATE = 31
        END IF
    END IF
    PRINT #2, "<CALL:";
    PRINT #2, RIGHT$(STR$(LEN(CALLSIGN$)), 1);
    PRINT #2, ">"; CALLSIGN$;
    IF FREQ$ = "1.8 " THEN PRINT #2, "<BAND:4>160M";
    IF FREQ$ = "3.5 " THEN PRINT #2, "<BAND:3>80M";
    IF FREQ$ = "7   " THEN PRINT #2, "<BAND:3>40M";
    IF FREQ$ = "14  " THEN PRINT #2, "<BAND:3>20M";
    IF FREQ$ = "18  " THEN PRINT #2, "<BAND:3>17M";
    IF FREQ$ = "21  " THEN PRINT #2, "<BAND:3>15M";
    IF FREQ$ = "24  " THEN PRINT #2, "<BAND:3>12M";
    IF FREQ$ = "28  " THEN PRINT #2, "<BAND:3>10M";
    IF FREQ$ = "50  " THEN PRINT #2, "<BAND:2>6M";
    IF FREQ$ = "144 " THEN PRINT #2, "<BAND:2>2M";
    IF FREQ$ = "430 " THEN PRINT #2, "<BAND:4>70CM";
    IF FREQ$ = "1200" THEN PRINT #2, "<BAND:4>23CM";
    PRINT #2, "<MODE:";
    PRINT #2, RIGHT$(STR$(LEN(MODE$)), 1);
    PRINT #2, ">"; MODE$;
    PRINT #2, "<QSO_DATE:8>";
    PRINT #2, RIGHT$(STR$(YEAR), 4);
    IF MONTH < 10 THEN
        PRINT #2, "0";
        PRINT #2, RIGHT$(STR$(MONTH), 1);
    ELSE
        PRINT #2, RIGHT$(STR$(MONTH), 2);
    END IF
    IF DATE < 10 THEN
        PRINT #2, "0";
        PRINT #2, RIGHT$(STR$(DATE), 1);
    ELSE
        PRINT #2, RIGHT$(STR$(DATE), 2);
    END IF
    PRINT #2, "<TIME_ON:4>";
    IF HOUR < 10 THEN
        PRINT #2, "0"; RIGHT$(STR$(HOUR), 1);
    ELSE
        PRINT #2, RIGHT$(STR$(HOUR), 2);
    END IF
    IF MIN < 10 THEN
        PRINT #2, "0"; RIGHT$(STR$(MIN), 1);
    ELSE
        PRINT #2, RIGHT$(STR$(MIN), 2);
    END IF
    PRINT #2, "<RST_SENT:";
    PRINT #2, RIGHT$(STR$(LEN(UR$)), 1);
    PRINT #2, ">"; UR$;
    PRINT #2, "<RST_RCVD:";
    PRINT #2, RIGHT$(STR$(LEN(MY$)), 1);
    PRINT #2, ">"; MY$;
    PRINT #2, "<EOR>"

NXTDATA:
WEND

CLOSE #1
CLOSE #2
※時刻をUTCに変換しなければなりません(9時間差し引く)が、それによって日付が前日に変わってしまう可能性があります。それが月初だと月が前月に変わってしまいます。それが年初だと年も前年に変わってしまいます。それが3月の頭だと前の月が28日あるのか29日なのか判別しなければなりません・・・とか考えると考慮点が多く、プログラムが長くなってしまいました。それと、移動局のコールサインはどこまでがコールサインなのか、という問題もありますが、一応、(例)JP3TLC/3のコールサインはJP3TLCまでとしています。移動先のADIFのタグは今後追加予定と聞いています。

E他の種類のカード未受領先からhQSLが届いていたら一覧表示するプログラム
	$lf=1;

	$hfilnam="";
	printf STDOUT "入力HARMONYファイル名(省略時TEMP.TXT):";
GETHNAM:
	$c=getc(STDIN);
	if($c ne "\n"){
		printf STDOUT "%s",$c;
		$hfilnam=$hfilnam.$c;
		goto GETHNAM;
	}
	if($hfilnam eq ''){$hfilnam="TEMP.TXT";}
	printf STDOUT "\n";

	$efilnam="";
	printf STDOUT "入力DIRファイル名(省略時DIR.TXT):";
GETENAM:
	$c=getc(STDIN);
	if($c ne "\n"){
		printf STDOUT "%s",$c;
		$efilnam=$efilnam.$c;
		goto GETENAM;
	}
	if($efilnam eq ''){$efilnam="DIR.TXT";}
	printf STDOUT "\n";

	$ofilnam="";
	printf STDOUT "出力ファイル名(省略時HQSL.TXT):";
GETONAM:
	$c=getc(STDIN);
	if($c ne "\n"){
		printf STDOUT "%s",$c;
		$ofilnam=$ofilnam.$c;
		goto GETONAM;
	}
	if($ofilnam eq ''){$ofilnam="HQSL.TXT";}
	printf STDOUT "\n";


	open FH,$efilnam;
	$i=0;
	while(eof(FH)==0){
		$line=<FH>
		$u=index($line,"_");
		if($u>0){
			$s=index($line,"           ");
			$ecall[$i]=substr($line,$s+19,$u-$s-19);
			$edate[$i]=substr($line,$u+1,6).substr($line,$u+8,4);
			$i++;
		}
	}
	close FH;

	$i--;
	$n=$i;
	$g=$n;


#############################
#        一巡目      #
#############################
#子があるうちで最大の添え字
	$k=int(($n-1)/2);
DECK:
	$l=$k;
#ヒープチェックと入れ替え
RECHK:
#そのノードと子ノード2つの3者を比較
	$a=$edate[$l];
	$b=$edate[$l*2+1];
#$cが存在するか調べて、あれば$cをセットし、なければ""
	if($l*2+2>$n){$c="";}else{$c=$edate[$l*2+2];}
#子を比較して大きいほうを選ぶ
	if($b gt $c){
		$d=$b;
		$m=$l*2+1;
	}else{
		$d=$c;
		$m=$l*2+2;
	}
#親より子が大きければ入れ替える
	$irekae=0;
	if($a<$d){
		$edate[$l]=$d;
		$edate[$m]=$a;
		$tmpcall=$ecall[$l];
		$ecall[$l]=$ecall[$m];
		$ecall[$m]=$tmpcall;
		$irekae=1;
	}
#入れ替えが発生したら入れ替え先を親として再度ヒープチェック
#子ありならチェック対象
	if($irekae==1 and $m*2+1<=$n){
		$l=$m;
		goto RECHK;
	}
#交換しなかった場合はつぎの親ノードをチェック
	$k--;
	if($k>-1){goto DECK;}
################################################
#     末尾切り落とし                      #
################################################
MCUT:

	$tmpdate=$edate[0];
	$edate[0]=$edate[$g];
	$edate[$g]=$tmpdate;

	$tmpcall=$ecall[0];
	$ecall[0]=$ecall[$g];
	$ecall[$g]=$tmpcall;

	$g--;
	if($g<1){goto CHKHM;}
################################################
#           二巡目以降                         #
################################################
	$l=0;
#ヒープチェックと入れ替え
RECHK2:
#そのノードと子ノード2つの3者を比較
	$a=$edate[$l];
	$b=$edate[$l*2+1];
#$cが存在するか調べて、あれば$cをセットし、なければ""
	if($l*2+2>$g){$c="";}else{$c=$edate[$l*2+2];}
#子を比較して大きいほうを選ぶ
	if($b gt $c){
		$d=$b;
		$m=$l*2+1;
	}else{
		$d=$c;
		$m=$l*2+2;
	}
#親より子が大きければ入れ替える
	$irekae=0;
	if($a<$d){
		$edate[$l]=$d;
		$edate[$m]=$a;
		$tmpcall=$ecall[$l];
		$ecall[$l]=$ecall[$m];
		$ecall[$m]=$tmpcall;
		$irekae=1;
	}
#入れ替えが発生したら入れ替え先を親として再度ヒープチェック
#子ありならチェック対象
	if($irekae==1 and $m*2+1<=$g){
		$l=$m;
		goto RECHK2;
	}
	goto MCUT;
################################################
#   HARMONYと突き合わせ              #
################################################
CHKHM:
	open FO,">".$ofilnam;

	for($z=0;$z<=$n;$z++){printf FO "%s %s\n",$edate[$z],$ecall[$z];}

	printf FO "【紙カード未着でHQSL到着】(頭部に*は当方のログに該当なし)\n";

	open FH,$hfilnam;

	$h=0;
	$i=-1;
NEXTHQSL:
	$i++;
	if($i==$n){exit;}
	$d=$edate[$i];
	$d=$d+0;
	$c=$ecall[$i];

NEXTHM:
	if($lf>10){
		$lf=1;
		printf FO "\n";
	}
	if(eof(FH)!=0){exit;}
	$line=<FH>
	if(substr($line,6,1) eq '1'){goto NEXTHM;}

	$hdate=substr($line,8,2).substr($line,0,2).substr($line,3,2).substr($line,11,2).substr($line,14,2);
	$hdate=$hdate+0;
	$hcall[$h]=substr($line,17,6);
	$hqsl[$h]=substr($line,84,1);

	$t=$h;

	$h++;
	if($h>1000){$h=0;}
	if($hdate < $d+10){goto NEXTHM;}

SEEKHM:


	if($c eq $hcall[$t]){
		if(($hqsl[$t] ne 'X')and($hqsl[$t] ne 'H')and($hqsl[$t] ne 'E')){
			printf FO " %s",$c;
			$lf++;
		}
		goto NEXTHQSL;
	}
	$t--;
	if($t<0){$t=1000;}
	if($t == $h){
		printf FO "*%s ",$c;
		$lf++;
		goto NEXTHQSL;
	}
	goto SEEKHM;


※このプログラムはPerlで作りました。入力ファイルが交信ログ@とhQSLの受領先一覧(後述)の二つですが、後者を日付・時間順にソートしなければ突合せできません(ソートしない場合は毎回全件サーチとなって待ち時間が非現実的)。DOSパソコンだと配列が1000個程度で早くも「メモリ不足です」エラーが出るので、ゆくゆく数万件まで増えることを考慮すると古いパソコンでは処理不可能と判断しました。ソートは高速と言われるヒープソートというアルゴリズムを使っています。ほとんど同じコードが2回登場するのでまとめることが可能なはずです。どんくさいプログラムですいません。hQSLの受領先一覧は下記バッチファイルをダブルクリックして作成してください。バッチで作成すると普通のシフトJISのファイルができるのに、PowerShell等に入って手動で作成すると文字コードがunicodeになってしまい、うまく動いてくれません。紙カードが未着でもhQSLが届いていればそれを印刷して1局ゲットです。(^_^)

cd \hamlog\受信
dir > \dir.txt
cd \


F他の種類のカード未受領先からeQSLが届いていたら一覧表示するプログラム
	$lf=1;
	$band='';
	$d='';

	$hfilnam="";
	printf STDOUT "入力HARMONYファイル名(省略時TEMP.TXT):";
GETHNAM:
	$c=getc(STDIN);
	if($c ne "\n"){
		printf STDOUT "%s",$c;
		$hfilnam=$hfilnam.$c;
		goto GETHNAM;
	}
	if($hfilnam eq ''){$hfilnam="TEMP.TXT";}
	printf STDOUT "\n";

	$efilnam="";
	printf"入力eQSLファイル名(省略時J4PGLC.ADI):";
GETENAM:
	$c=getc(STDIN);
	if($c ne "\n"){
		printf STDOUT "%s",$c;
		$efilnam=$efilnam.$c;
		goto GETENAM;
	}
	if($efilnam eq ''){$efilnam="J4PGLC.ADI";}
	printf STDOUT "\n";

	$ofilnam="";
	printf"出力ファイル名(省略時EQSL.TXT):";
GETONAM:
	$c=getc(STDIN);
	if($c ne "\n"){
		printf STDOUT "%s",$c;
		$ofilnam=$ofilnam.$c;
		goto GETONAM;
	}
	if($ofilnam eq ''){$ofilnam="EQSL.TXT";}
	printf STDOUT "\n";

	open FO,">".$ofilnam;
	open FH,$hfilnam;
	open FJ,$efilnam;

	printf FO "【紙カード未着でeQSL到着】(頭部に*は当方のログに該当なし)\n";

	$h=0;
NEXTEQSL:
	if(eof(FJ)!=0){exit;}
	$buf=<FJ>
	if(substr($buf,0,6) ne'<CALL:'){goto NEXTEQSL;}

	$bc=$c;
	$col=substr($buf,6,1);
	if($col lt '3'){goto NEXTEQSL;}
	if($col gt '5'){$c=substr($buf,8,6);}
	if($col eq '3'){$c=substr($buf,8,3).'   '}
	if($col eq '4'){$c=substr($buf,8,4).'  '}
	if($col eq '5'){$c=substr($buf,8,5).' '}

	$bband=$band;
	$col=index($buf,'<BAND:');
	$mojisu=substr($buf,$col+6,1);
	$mojisu=$mojisu+0;
	$band=substr($buf,$col+8,$mojisu);

	$bd=$d;
	$col=index($buf,'<QSO_DATE:8:D>');
	$dyear=substr($buf,$col+14,4);
	$dyear=$dyear+0;
	$dmonth=substr($buf,$col+18,2);
	$dday=substr($buf,$col+20,2);
	$dday=$dday+1;
	if(($dmonth eq '12')and($dday > 31)){$dmonth='01';$dday=1;$dyear++;}
	if(($dmonth eq '11')and($dday > 30)){$dmonth='12';$dday=1;}
	if(($dmonth eq '10')and($dday > 31)){$dmonth='11';$dday=1;}
	if(($dmonth eq '09')and($dday > 30)){$dmonth='10';$dday=1;}
	if(($dmonth eq '08')and($dday > 31)){$dmonth='09';$dday=1;}
	if(($dmonth eq '07')and($dday > 31)){$dmonth='08';$dday=1;}
	if(($dmonth eq '06')and($dday > 30)){$dmonth='07';$dday=1;}
	if(($dmonth eq '05')and($dday > 31)){$dmonth='06';$dday=1;}
	if(($dmonth eq '04')and($dday > 30)){$dmonth='05';$dday=1;}
	if(($dmonth eq '03')and($dday > 31)){$dmonth='04';$dday=1;}
	if($dmonth eq '02'){
		if(($dyear/4 == int($dyear/4))and($dday > 29)){$dmonth='03';$dday=1;}
		if(($dyear/4 != int($dyear/4))and($dday > 28)){$dmonth='03';$dday=1;}
	}
	if(($dmonth eq '01')and($dday > 31)){$dmonth='02';$dday=1;}
	$dyear=$dyear.'';
	if($dday<10){$dday='0'.$dday;}else{$dday=$dday.'';}
	$d=$dyear.$dmonth.$dday;

	if(($bc eq $c)and($bband eq $band)and($bd eq $d)){goto NEXTEQSL;}

NEXTHM:
	if($lf>10){
		$lf=1;
		printf FO "\n";
	}
	if(eof(FH)!=0){exit;}
	$line=<FH>

	$hdate=substr($line,6,4).substr($line,0,2).substr($line,3,2);
	$hcall[$h]=substr($line,17,6);
	$hqsl[$h]=substr($line,84,1);

	$t=$h;

	$h++;
	if($h>1000){$h=0;}

	if($hdate<=$d){goto NEXTHM;}

SEEKHM:

	if($c eq 'JQ1ARQ'){goto NEXTEQSL;}
	if($c eq 'JA1443'){goto NEXTEQSL;}

	if($c eq $hcall[$t]){
		if($hqsl[$t] eq ' '){
			printf FO " %s",$c;
			$lf++;
		}
		goto NEXTEQSL;
	}
	$t--;
	if($t<0){$t=1000;}
	if($t == $h){
		printf FO "*%s",$c;
		$lf++;
		goto NEXTEQSL;
	}
	goto SEEKHM;


※Eと同じプログラムのeQSL版です。入力ファイルはEと同様に交信ログ@とeQSLの受領先一覧(後述)の二つです。eQSLの受領先一覧は下記リンクから取得してください。「InBox」か「Archive」のどちらかを押して一番下にあります。どちらを選んでも同じファイルがDLできます。左クリックするとファイルの内容がブラウザに表示されてしまう場合は右クリックしてファイルを保存してください。毎回末尾の数字(ファイル取得時刻か?)が変わって面倒なのでファイル名をJ4PGLC.ADIに変えてください。紙カードが未着でもeQSLが届いていればそれを印刷して1局ゲットです。(^_^) このプログラムは突合せ時に翌日まで対象にしています。その理由は、当方の交信データは2014年より前は紙ログを使っていてパソコンはQSL受領とJCC・JCGの管理にしか使っていなかったので時刻やシグナルレポートが入力されていません。しかもeQSLはUTC、自分はJSTなので翌日まで対象にしないと該当なしになる可能性があります。そのためコールサインは一致しているものの、関係ないQSOを紐付けてしまう可能性がありますが、あしからずご了承ください。
eQSLログ取得先

「無線」メニュー
このホームページの内容についてのご意見ご感想は jp3tlc@jarl.com までお願いします。返信を希望される場合はGmailからのメールを受信できるようにしてください。
HOME 無線 PC−1245 MSX ファミコン 迷路
パソコン通信 売店 病院 PC−9800 PDA 太陽光発電 経済