我正在创建一个Web应用程序来替换当前的Excel宏应用程序。 Excel宏中包含多个表单和模块。当我使用xlApp.Run方法在C#中调用宏函数时,函数被调用但在函数调用其他子函数并使用全局公共变量时抛出错误。
错误: 1.编译错误:Sub或Function未定义 - 在“Set svd = m_queries(GetSheetRootName(Sheet1))” 2.运行时错误424:对象必需 - 在“CompareWorksheetsToCombined”
代码:
Public Function CompareExcels(filePath1 As String, filePath2 As String)
Call MsgBox("Done comparing sheets1.", vbInformation, "Compare Complete")
On Error GoTo CompErr
Call MsgBox("Done comparing sheets2.", vbInformation, "Compare Complete")
Dim compBook As Workbook
Dim book1 As Workbook, book2 As Workbook
Dim sheet, Sheet1 As Worksheet, Sheet2 As Worksheet
Dim svd As ScriptViewDescription, obj
Dim l As Long
Dim sheetName As String
Dim a As Integer
'// Check to make sure we have valid options selected for compare
If ValidateOptions = False Then Exit Function
cmdCompare.Enabled = True
'// Create the comparison output workbook
Set compBook = OpenCompareOutput()
'// Get the workbooks we're comparing
Set book1 = Workbooks(filePath1)
Set book2 = Workbooks(filePath2)
'// Verify if the Summary Sheet Exists and compare the libraries.
'//If (WorksheetExists("[" & filePath1 & "]Summary")) And (WorksheetExists("[" & filePath2 & "]Summary")) Then
Set Sheet1 = book1.Sheets("Summary")
Set Sheet2 = book2.Sheets("Summary")
'//If Sheet1.Cells(2, 3) = Sheet2.Cells(2, 3) Then
'// a = MsgBox("Attention: You are comparing the data from Same Environment", vbCritical, "Critical Warning")
'//End If
'//Else
'//a = MsgBox("Summary Tab does not exist in either Workbook A or B and the Libraries are not compared", vbCritical, "Critical Warning")
'//End If
'// Look for selected sheets and then compare them
For l = 0 To lstSheets.ListCount - 1
If lstSheets.selected(l) = True Then
'// reset vars to make sure we don't accidentally re-use from last loop
Set Sheet1 = Nothing
Set Sheet2 = Nothing
Set svd = Nothing
'// Attempt to load up the vars with the new stuff
sheetName = lstSheets.list(l)
Set Sheet1 = book1.Sheets(sheetName)
Set Sheet2 = book2.Sheets(sheetName)
Set svd = m_queries(GetSheetRootName(Sheet1))
'// Check vars and if we're good then compare
If Not (Sheet1 Is Nothing) _
And Not (Sheet2 Is Nothing) _
And Not (svd Is Nothing) Then
Call CompareWorksheetsToCombined(Sheet1, Sheet2, compBook, svd, txtPrefixA.Text, txtPrefixB.Text)
End If
End If
Next l
cmdCompare.Enabled = True
Call MsgBox("Done comparing sheets.", vbInformation, "Compare Complete")
Exit Function
CompErr:
Call MsgBox("Error while attempting to process compares." & vbCrLf & vbCrLf & "Error " & Err.Number & ": " & Err.Description, vbCritical, "Error During Compare")
cmdCompare.Enabled = True
End Function
请帮忙。
答案 0 :(得分:1)
我不久前写了一些软件,在关闭之前运行一个宏。
Microsoft.Office.Interop.Excel.Document.ActiveDocument.Application.Run("macroName")
请参阅: https://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.aspx
这是一些使用Interop.Word修剪过的VB,应该很容易移植。
Imports Word = Microsoft.Office.Interop.Word
Dim objWordApp As New Word.Application
Dim objDoc As Word.Document
Private Sub Form1_Load(ByVal sender As System.Object, e As System.EventArgs) Handles MyBase.Load
'Establish application path, replace appPath on deployment
Dim appPath As String = Application.StartupPath()
'Run application in foreground or background.
'If in background (false), be sure to add objDoc.close() and objWordApp.Quit()
objWordApp.Visible = False
Dim objDoc As Word.Document = objWordApp.Documents.Open(appPath & "path.to.file", [ReadOnly]:=True)
objDoc = objWordApp.ActiveDocument
With objDoc
...Manipulate document...
End With
'clear objDoc object
objDoc = Nothing
'quit msWord
lblStatus.Text = "Quitting MS Word"
objWordApp.Quit()
'clear objWord object
objWordApp = Nothing
'close com objects on parent system
lblStatus.Text = "Releasing COM objects"
If Not objDoc Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(objDoc)
End If
If Not objWordApp Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(objWordApp)
End If
'set filename
lblStatus.Text = "Sending BLOB to DB"
Dim filename As String = Path.GetFileName(saveString)
'open a filestream
Dim fs As FileStream = New FileStream(saveString, FileMode.Open, FileAccess.Read)
'open a binary reader stream
Dim br As BinaryReader = New BinaryReader(fs)
'create array to store the BLOB
Dim bytes As Byte() = br.ReadBytes(Convert.ToInt32(fs.Length))
'Write the BLOB to the DB and set box as unselected
Dim cmdStoreBlob As SqlCommand = New SqlCommand("UPDATE TABLENAME SET
COLUMN = @VAR, [SELECTED] = @VAR2 WHERE [SELECTED] = 'True'", connection)
cmdStoreBlob.Parameters.Add("@VAR1", SqlDbType.VarBinary).Value = bytes
cmdStoreBlob.Parameters.Add("@VAR2", SqlDbType.Bit).Value = 0
cmdStoreBlob.ExecuteNonQuery()
'close binary reader and file stream
lblStatus.Text = "Cleaning Up"
br.Close()
fs.Close() 'close file stream
'close SQL server connection
connection.Close()
'exit application
Application.Exit()
End Sub
End Class
答案 1 :(得分:0)
我们假设你有一个看起来像这样的Excel宏
Sub ShowMsg(msg As String, title As String)
MsgBox msg, vbInformation, title
End Sub
这是将参数传递给该宏然后调用它的C#代码。 (使用VS2010 + Excel 2010进行测试和测试)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//~~> Define your Excel Objects
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlWorkBook;
//~~> Start Excel and open the workbook.
xlWorkBook = xlApp.Workbooks.Open("E:\\Users\\Siddharth Rout\\Desktop\\book1.xlsm");
//~~> Run the macros by supplying the necessary arguments
xlApp.Run("ShowMsg", "Hello from C# Client", "Demo to run Excel macros from C#");
//~~> Clean-up: Close the workbook
xlWorkBook.Close(false);
//~~> Quit the Excel Application
xlApp.Quit();
//~~> Clean Up
releaseObject(xlApp);
releaseObject(xlWorkBook);
}
//~~> Release the objects
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
}
finally
{
GC.Collect();
}
}
}
}
答案 2 :(得分:0)
问题是什么?它没有用?在我工作时,我无法测试这些东西;我机器上的所有东西都完全锁定了。如果计算机打开电话我很幸运...
我知道,下面的脚本肯定会有效。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;
namespace WindowsFormsApplication5
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//"http://programmingeveryday.wordpress.com/2013/02/20/run-excel-macro-programmatically-in-c/"
//~~> Define your Excel Objects
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlWorkBook;
//~~> Start Excel and open the workbook.
xlWorkBook = xlApp.Workbooks.Open("C:\\Users\\Ryan\\Desktop\\RunMacro.xlsb");
//~~> Run the macros by supplying the necessary arguments
xlApp.Run("ShowMessage");
//~~> Clean-up: Close the workbook
xlWorkBook.Close(false);
//~~> Quit the Excel Application
xlApp.Quit();
//~~> Clean Up
releaseObject(xlApp);
releaseObject(xlWorkBook);
}
//~~> Release the objects
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
}
finally
{
GC.Collect();
}
}
}
}