如何将参数作为参数从excel中的VBA脚本传递到外部可执行文件(C#)?

如何将参数作为参数从excel中的VBA脚本传递到外部可执行文件(C#)?,c#,vba,excel,solidworks,C#,Vba,Excel,Solidworks,我在excel工作表中嵌入了一个按钮,用于调用VBA脚本。在这个脚本中,我读取当前目录,进行解析,并使用它生成值,将字符串[]args传递给外部C#可执行文件。我已经进行了多次迭代,它确实调用了可执行文件,但是当C#.exe运行时,传递的参数似乎为null(空)。我可以在其他程序中使用此C#.exe并传递参数,但此VBA脚本无法按预期工作。我还知道它正在传递正确的参数,因为我没有从C#exe获得越界异常。我目前正在将所有这些参数转换为字符串,试图对此进行故障排除,但这很可能不是必需的。附加VBA

我在excel工作表中嵌入了一个按钮,用于调用VBA脚本。在这个脚本中,我读取当前目录,进行解析,并使用它生成值,将字符串[]args传递给外部C#可执行文件。我已经进行了多次迭代,它确实调用了可执行文件,但是当C#.exe运行时,传递的参数似乎为null(空)。我可以在其他程序中使用此C#.exe并传递参数,但此VBA脚本无法按预期工作。我还知道它正在传递正确的参数,因为我没有从C#exe获得越界异常。我目前正在将所有这些参数转换为字符串,试图对此进行故障排除,但这很可能不是必需的。附加VBA代码:

Sub ButtonSG1b7_Click()

Dim FileLocation
Dim ProgramName
Dim length

FileLocation = ActiveWorkbook.FullName
length = Len(FileLocation) - 5
ProgramName = Left(FileLocation, length)
ProgramName = Right(ProgramName, 10)
length = Len(FileLocation) - 15
FileLocation = Left(FileLocation, length)
length = Len(FileLocation) - 2
FileLocation = Right(FileLocation, length)

MsgBox "File Location : " & FileLocation & "    Program Name: " & ProgramName

Dim str0 As String
Dim str1 As String
Dim str2 As String
Dim str3 As String
Dim str4 As String
Dim str5 As String
Dim str6 As String

str0 = "H:\StageGate\Administration\Scripts\GetLatestFileOpen.exe "
str1 = "H:"
str2 = FileLocation
str3 = "Common"
str4 = "\Market Feasibility "
str5 = ProgramName
str6 = ".xlsx"


MsgBox str0 & str1 & str2 & str3 & str4 & str5 & str6
Shell (str0 & str1 & str2 & str3 & str4 & str5 & str6)

End Sub
编辑(添加涉及Solidworks EPDM库的prelim C#代码,该库接受参数,将其转换为列表,并使用该列表提供字符串文件路径,以获取EPDM vault中文件夹的最新信息,然后打开文件的更新本地副本):

使用系统;
使用系统诊断;
使用System.Windows.Forms;
使用System.Collections.Generic;
使用System.Linq;
使用System.IO;
使用EPDM.Interop.EPDM;
班级计划
{
静态void Main(字符串[]参数)
{
IEdmFolder5 ppoRetParentFolder;
列表文件路径=新列表(args);
if(filePath.Any())
{
filePath.RemoveAt(0);//确实需要停止让脚本调用传递此参数。
}
如果(目录.Exists(@“C:\StageGate”)){
插入(0,“C:”);
}
else if(目录.Exists(@“H:\StageGate”))
{
插入(0,“H:”);
}
其他的
{
MessageBox.Show(“StageGate未找到”);
}
string newFilePath=string.Join(“,filePath.ToArray());
filePath.RemoveAt(5);
filePath.RemoveAt(4);
filePath.RemoveAt(3);
string folderPathstr=string.Join(“,filePath.ToArray());
//MessageBox.Show(folderPathstr);
//必须创建vault对象才能使用BatchGet
EdmVault5 vault=新的EdmVault5();
//用您的保险库名称替换我的保险库
保险库。登录(“StageGate”,0);
//将此处的2设置为要获取的文件夹数(不包括子文件夹)
EdmSelItem[]folderArray=新的EdmSelItem[1];
IEdmBatchGet bg=(IEdmBatchGet)vault.CreateUtility(EdmUtility.EdmUtil\u BatchGet);
//为要获取的每个文件夹创建和数组元素,用文件夹替换文件夹位置
folderArray[0].mlDocID=0;
folderArray[0].mlProjID=vault.GetFolderFromPath(folderPathstr).ID;
//fa[1].mlDocID=0;
//fa[1].mlProjID=vault.GetFolderFromPath(“C:\\My\U vault\\FolderPath”).ID;
背景添加选择(保险库、文件夹阵列);
bg.CreateTree(0,(int)EdmGetCmdFlags.Egcf_IncludeAutoCacheFiles);//Egcf_IncludeAutoCacheFiles将获取文件的最新版本
bg.GetFiles(0,空);
if(File.Exists(newFilePath))
{
Process Process=Process.Start(newFilePath);//不能只打开文件。需要创建新的windows进程才能在默认应用程序(进程)中打开文件
//File.Open(newPath,FileMode.Open);
}
其他的
{
Show(“未找到文件”);
} 
阅读C代码后,我发现您的代码至少需要6个参数

此VBA代码将转义路径中可能出现的任何空格,并将其作为命令行参数传递:

Sub ButtonSG1b7_Click()

Dim FileLocation
Dim ProgramName
Dim length

FileLocation = ActiveWorkbook.FullName
length = Len(FileLocation) - 5
ProgramName = Left(FileLocation, length)
ProgramName = Right(ProgramName, 10)
length = Len(FileLocation) - 15
FileLocation = Left(FileLocation, length)
length = Len(FileLocation) - 2
FileLocation = Right(FileLocation, length)

MsgBox "File Location : " & FileLocation & "    Program Name: " & ProgramName

Dim args(0 To 6) As String
Dim cmdln As String, i as Integer

args(0) = "H:\StageGate\Administration\Scripts\GetLatestFileOpen.exe"
args(1) = "H:"
args(2) = FileLocation
args(3) = "Common"
args(4) = "\Market Feasibility "
args(5) = ProgramName
args(6) = ".xlsx"

cmdln=arg(0)
For i = 1 To 6
cmdln=cmdln & " """ & args(i) & """"
Next i
MsgBox "VBA Code Writes: " & cmdln
Shell (cmdln)

End Sub
现在,您的c#代码应该读取这些参数:

class Program
{
static void Main(string[] args)
{
Console.WriteLine("C# Code Reads: "+String.Join(" ", args));
}
}

如果这两个进程返回相同的命令行字符串,那么您在以下行中可能遇到的任何异常都与VBA-C#communications无关

因为第二个参数中有一个空格,您是否尝试在字符串的任一侧使用“将其指定为单个参数而不是两个(或更多,取决于空格)?我需要脚本传递6个参数,因为这是C#程序所期望的。将其指定为单个参数会导致C#exe抛出System.OutofRange异常。我必须以这种方式编写脚本,因为所使用的EPDM vault不包括将参数格式化为一个字符串的方法,所以我传递了所需的6个变量es.无论如何,任何带有空格的内容都需要转义。例如,\市场可行性将被解释为两个参数,而不是一个。这导致它现在给我一个System.ArgumentOutOfRange错误,而不是空错误。我将编辑原始帖子以包含C代码。这是一个巨大的进步:-)如果这个答案有用,请接受答案,或者至少向上投票,离开工作,没有时间检查。当我获得更多的代表分数并检查答案后,我肯定会向上投票。我必须对文件位置结构进行一些更改,但它正在工作。我将此移到excel中的外部脚本的原因之一工作表是,您无法在excel中打开另一个excel文件。外部C#脚本非常适合于此。感谢您的帮助!如果您得到代表,请向上投票我的问题。我希望再获得5个,以便能够向上投票给其他人!
class Program
{
static void Main(string[] args)
{
Console.WriteLine("C# Code Reads: "+String.Join(" ", args));
}
}