通常交信とコンテストのログに使っているjg6jav_log.xlsmの周波数とモードの情報は、C#で作った無線機のコントローラーIC7851RCから取得している。従前は、Clipboardを使って取得して記入していたがそれがうまくいかない事例が最近頻繁に発生して困っている。なのでなんとか直接取得できないかいろいろ調べていたらC#からExcelのVBA標準モジュールを起動できることが判った。渡したい情報を引数にしてしまえば目的を果たせる。その情報をどう扱うかは、Excel VBA側に目的シートの何処にそれらを情報を転記するかなどの処理を任せることで解決した。正直Clipboardを使った方が扱い易く動作も速かったように思うけれどもClipboardが時々正常に動作せず情報が転記されないという問題は解決した。
C# IC7851RCから情報をExcelへ渡す
// -- IC7851RC ---
using Microsoft.VisualBasic;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
//
// EXCELへ情報転記 Run Excel VBA
private void Send_RigInfo(int RunNr, bool Boo = false, string callsign = "")
{
try
{
Process[] ps = Process.GetProcessesByName("Excel");
if (ps.Length < 0) return;
Interaction.AppActivate(ps[0].Id);
var XLS = (Excel.Application)Marshal.GetActiveObject("Excel.Application");
var WB = (Excel.Workbook)XLS.ActiveWorkbook;
if (WB.Name != "jg6jav_log.xlsm") return;
var Sh = (Excel.Worksheet)WB.ActiveSheet;
if (Sh.Name != "Contest" && Sh.Name != "QSO LOG") return;
string CallName = RunNr switch
{
1 => "RcvRigInfo",
2 => "StatusCheck",
_ => ""
};
XLS.Run(CallName, Boo, RI.Freq, LogMode, RI.RFP, callsign);
Marshal.ReleaseComObject(XLS);
}
catch (System.Exception ex)
{
StatusLabel.Text = ex.Message;
}
}
//
// Excel から SendKey CTRL+I or CTRL+W で作動
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
Keys KeyTop = e.KeyCode;
if (e.Control)
{ // [ctrl]+
switch (KeyTop)
{
case Keys.I:
Send_RigInfo(1, true);
break;
case Keys.W: // Rig Info to Excel
Send_RigInfo(1,false);
break;
}
}
}
Excel側からリクエストがなくても運用バンドが変更になったらこのメソッドはNoPost=trueで実行される。これで現在運用中のバンドが把握できるようになった。仔細は割愛するがIC7851RC内からはKeyDownイベントと周波数が変わった時に発動するメソッドとCW送出メソッド内でもこのメソッドは条件により実行される。
情報受け取りExcel VBA
'---// IC7851RCからRun実行により情報取得//---
Private Sub RcvRigInfo(NoPost As Boolean, rFreq As Variant, rMode As Variant, rPower As Variant, rCallsign As Variant)
Dim aRow As Long
Dim Sw As Boolean
rigFreq = rFreq
rigMode = rMode
rigPower = rPower
rigBand = Band(rigFreq)
If NoPost Then Exit Sub
RcvInfo = True
aRow = PostingCell.Row
If Application.EnableEvents Then
Sw = True
Call AppLock
End If
Select Case ActiveSheet.Name
Case "Contest"
If rCallsign <> "" Then
Call StatusCheck(False)
Cells(aRow, 6).Value = rCallsign
End If
With Cells(aRow, 4)
If .Value <> rigFreq Then .Value = rigFreq
End With
With Cells(aRow, 5)
If .Value <> rigMode Then .Value = rigMode
End With
Case "QSO LOG"
If rCallsign <> "" Then Cells(aRow, 4).Value = rCallsign
Cells(aRow, 7).Value = rigFreq
Cells(aRow, 8).Value = rigMode
Cells(aRow, 9).Value = rigPower
End Select
If Sw Then AppReset
End Sub
'
'---// IC7851RCからRun実行により情報取得とConest Run/S%P状態切り換え //---
Sub StatusCheck(Sw As Boolean, Optional rFreq As Variant = 0, Optional rMode As Variant = 0, _
Optional rPower As Variant = 0, Optional Void = "")
If rFreq > 0 Then
rigFreq = rFreq
rigMode = rMode
rigPower = rPower
End If
With ActiveSheet
If .Name <> "Contest" Then
Exit Sub
End If
With .CheckBox1
If .Value = Sw Then Exit Sub
.Value = Sw
End With
End With
End Sub
'
'---// IC7851RCへ情報取得要求 SKey "^W"(STRL+W)or "^I"(CTRL+I) //
Sub GetRigInfo(SKey As String)
On Error Resume Next
Set PostingCell = ActiveCell
AppActivate "IC-7851"
SendKeys (SKey)
AppActivate Application.Caption
On Error GoTo 0
End Sub
VBAからC#のメソッド起動は、IC7851RCにSendKeysで行い目的のメソッドを実行させる。コンテストでは、交信最終CWメッセージ終端にトリガー文字列を含ませることでIC7851RCのメソッドが実行されるようにした。
コメント