自动化 MS Access VBA 过程 - 将字符串变量分配给 InputBox
Automating MS Access VBA procedure - assign string variable to InputBox
我正在尝试通过 C# 自动执行乍一看非常简单的任务 - 将字符串值传递给通过 VBA 函数调用的 inputBox。
为此,我使用 Visual C# .NET Automation Client 创建了一个 MS Access 实例并打开了所需的数据库:
using System.Management.Automation;
using Access = Microsoft.Office.Interop.Access;
Access.Application oAccess = new Access.Application();
oAccess.Visible = true;
oAccess.OpenCurrentDatabase("D:\path\to\database", false, "");
在提到的数据库中,我们有一个通过“RunCode
”操作调用 VBA 函数的宏。这个 public Function
然后调用另一个 private Sub
:
Public Function ImportMappingDatabases()
ImportMappings InputBox("Specify Path", "Path", mstrcDefaultPath), _
InputBox("Choose Package", "Package", "")
End Function
Private Sub ImportMappings(Optional Path As String = mstrcDefaultPath, Optional Package As String = "")
这是我卡住的地方。标题为“Path
”的输入框希望用户输入后面代码使用的某个路径,原因不用解释。对于标题为“Package
”的输入框同样有效。我假设有一种方法可以将字符串值从 C# 代码“传递”到输入框输入字段,但我不知道如何引用输入框并设置该值。完成后,用户需要点击“确定”按钮或“取消”按钮,同样的问题适用,我将尝试用1句话综合它:
如何获取该输入框的引用、设置输入值并“单击”其中一个按钮?
更多信息:
我通过以下方式调用 public 函数:oAccess.Run("ImportMappingDatabases");
我可以不能修改VBAfunctions/subs。
更新 1:
在下方查看我的回答。
我找到了获取输入框句柄的方法以及将字符串值传递给它的方法。您需要以下导入:
[DllImport("User32.dll", CharSet = CharSet.Auto)] static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("User32.dll", CharSet = CharSet.Auto)] static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter,
string lpcClassName, string lpcWindowTitle);
[DllImport("User32.dll", CharSet = CharSet.Auto)] static extern UInt32 SendMessage(IntPtr handle, UInt32 message,
IntPtr wParam, string lParam);
然后您可以使用 Win API 调用来查找您的 MS Access window 和 inputBox window 句柄:
IntPtr parent = FindWindow(null, "The access Window title here");
IntPtr childInputBox = IntPtr.Zero;
IntPtr TextBox = IntPtr.Zero;
if (parent != IntPtr.Zero)
{
childInputBox = FindWindowEx(parent, IntPtr.Zero, string.Empty, "InputBox name here");
if (childInputBox != IntPtr.Zero)
{
TextBox = FindWindowEx(childInputBox, IntPtr.Zero, "Edit",
string.Empty);
if (TextBox != IntPtr.Zero)
{
SendMessage(TextBox, WM_SETTEXT, new IntPtr(0), "Your out string to the input here");
}
}
}
我在这里碰壁了,因为我实际上必须在尝试捕获句柄之前调用我的宏。所以调用宏:
oAccess.Run("TheNameOfTheMacro");
将 运行 它放在同一个线程上,因此使我们的 Window 表单应用程序在宏完成之前无法使用。
这种复杂性使我获得了使用接受字符串作为参数的 public 函数扩展 VBA 代码的许可(如评论中所述),并从那里继续。
如果您决定必须使用输入框,则必须 运行 不同线程上的宏并以某种方式检查输入框是否被“召唤”,如果是 - 发送消息。
我正在尝试通过 C# 自动执行乍一看非常简单的任务 - 将字符串值传递给通过 VBA 函数调用的 inputBox。
为此,我使用 Visual C# .NET Automation Client 创建了一个 MS Access 实例并打开了所需的数据库:
using System.Management.Automation;
using Access = Microsoft.Office.Interop.Access;
Access.Application oAccess = new Access.Application();
oAccess.Visible = true;
oAccess.OpenCurrentDatabase("D:\path\to\database", false, "");
在提到的数据库中,我们有一个通过“RunCode
”操作调用 VBA 函数的宏。这个 public Function
然后调用另一个 private Sub
:
Public Function ImportMappingDatabases()
ImportMappings InputBox("Specify Path", "Path", mstrcDefaultPath), _
InputBox("Choose Package", "Package", "")
End Function
Private Sub ImportMappings(Optional Path As String = mstrcDefaultPath, Optional Package As String = "")
这是我卡住的地方。标题为“Path
”的输入框希望用户输入后面代码使用的某个路径,原因不用解释。对于标题为“Package
”的输入框同样有效。我假设有一种方法可以将字符串值从 C# 代码“传递”到输入框输入字段,但我不知道如何引用输入框并设置该值。完成后,用户需要点击“确定”按钮或“取消”按钮,同样的问题适用,我将尝试用1句话综合它:
如何获取该输入框的引用、设置输入值并“单击”其中一个按钮?
更多信息:
我通过以下方式调用 public 函数:oAccess.Run("ImportMappingDatabases");
我可以不能修改VBAfunctions/subs。
更新 1:
在下方查看我的回答。
我找到了获取输入框句柄的方法以及将字符串值传递给它的方法。您需要以下导入:
[DllImport("User32.dll", CharSet = CharSet.Auto)] static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("User32.dll", CharSet = CharSet.Auto)] static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter,
string lpcClassName, string lpcWindowTitle);
[DllImport("User32.dll", CharSet = CharSet.Auto)] static extern UInt32 SendMessage(IntPtr handle, UInt32 message,
IntPtr wParam, string lParam);
然后您可以使用 Win API 调用来查找您的 MS Access window 和 inputBox window 句柄:
IntPtr parent = FindWindow(null, "The access Window title here");
IntPtr childInputBox = IntPtr.Zero;
IntPtr TextBox = IntPtr.Zero;
if (parent != IntPtr.Zero)
{
childInputBox = FindWindowEx(parent, IntPtr.Zero, string.Empty, "InputBox name here");
if (childInputBox != IntPtr.Zero)
{
TextBox = FindWindowEx(childInputBox, IntPtr.Zero, "Edit",
string.Empty);
if (TextBox != IntPtr.Zero)
{
SendMessage(TextBox, WM_SETTEXT, new IntPtr(0), "Your out string to the input here");
}
}
}
我在这里碰壁了,因为我实际上必须在尝试捕获句柄之前调用我的宏。所以调用宏:
oAccess.Run("TheNameOfTheMacro");
将 运行 它放在同一个线程上,因此使我们的 Window 表单应用程序在宏完成之前无法使用。 这种复杂性使我获得了使用接受字符串作为参数的 public 函数扩展 VBA 代码的许可(如评论中所述),并从那里继续。 如果您决定必须使用输入框,则必须 运行 不同线程上的宏并以某种方式检查输入框是否被“召唤”,如果是 - 发送消息。