我已经与VBA合作了几年,但我转而使用VB来利用更强大的编码实践。
我有以下VB代码将Excel工作簿附加到打开的实例:
Dim FullFilePath as String = "C:\Temp"
Dim WrkBk = as Excel.Workbook
WrkBk = System.Runtime.InteropServices.Marshal.BindToMoniker(FullFilePath)
这似乎需要工作簿的目录路径。
我有以下代码来循环使用Excel流程。
FileName = "ABCD.xlsm"
For Each P As Process In System.Diagnostics.Process.GetProcessesByName("EXCEL")
With P
If .MainWindowTitle.ToLower.Contains(FileName.ToLower) Then
'don't know the code to get the directory where the p process is located
WrkBk = System.Runtime.InteropServices.Marshal.BindToMoniker(FilePath)
Exit For
End If
End With
Next
ABCD.xlsm的路径并不总是与我的应用程序相同。获取进程目录的所有内容都会返回EXCEL.EXE路径或返回vb项目工作目录的路径。我真的需要它返回类似的东西:“C:\ Temp \ Tools \ ABCD.xlsm”所以我可以将WrkBk附加到进程中。
任何想法?有更简单的方法吗?
答案 0 :(得分:0)
Dim xl As Excel.Application
xl = GetObject(, "Excel.Application")
For Each wb As Excel.Workbook In xl.Workbooks
MsgBox(wb.FullName)
Next wb
xl = Nothing
答案 1 :(得分:0)
我终于找到了它。
Windows API ....
Private Delegate Function EnumWindowsProc(ByVal hwnd As IntPtr, ByVal lParam As IntPtr) As Boolean
Private Declare Function EnumChildWindows Lib "user32.dll" (ByVal hWndParent As IntPtr, ByVal lpEnumFunc As EnumWindowsProc, ByVal lParam As IntPtr) As Boolean
Private Declare Function GetClassName Lib "user32.dll" Alias "GetClassNameA" (ByVal hwnd As IntPtr, ByVal lpClassName As String, ByVal nMaxCount As Int32) As Int32
Private Const MAX_TITLE As Int32 = 256
Private Const S_OK As Int32 = &H0
Private Function GetClassName(ByVal hwnd As IntPtr) As String
Dim name As New String(" "c, MAX_TITLE)
Dim len = GetClassName(hwnd, name, MAX_TITLE)
If len = 0 Then Return Nothing
Return name.Remove(len)
End Function
Private Declare Function AccessibleObjectFromWindow Lib "OLEACC.dll" (ByVal hwnd As IntPtr, ByVal dwId As Int32, ByVal riid As Byte(), ByRef ppvObject As IntPtr) As Integer
Private Const OBJID_NATIVEOM As Int32 = &HFFFFFFF0
Private IID_IDispatch As New Guid("{00020400-0000-0000-C000-000000000046}")
...功能
Function EnumCWindows(ByVal hwnd As IntPtr, ByVal lParam As IntPtr) As Boolean
Dim name = GetClassName(hwnd)
If name = "EXCEL7" OrElse name = "EXCEL10" Then
Dim ptr As IntPtr
If AccessibleObjectFromWindow(hwnd, OBJID_NATIVEOM, IID_IDispatch.ToByteArray(), ptr) = S_OK Then
Dim win = CType(Marshal.GetObjectForIUnknown(ptr), Excel.Window)
Dim sheet = CType(win.ActiveSheet, Excel.Worksheet)
Dim book = CType(sheet.Parent, Excel.Workbook)
If book.FullName.ToLower.Contains("wpp tools") Then
FoundTheFile = True
WPPFilePath = book.FullName
Exit Function
End If
End If
End If
Return True
End Function
然后在你的代码....
For Each p In Process.GetProcesses
If p.ProcessName = "EXCEL" Then
EnumChildWindows(p.MainWindowHandle, AddressOf EnumCWindows, IntPtr.Zero)
If FoundTheFile = True Then Exit For
End If
Next
If FoundTheFile = False Then
MsgBox("Targeted file was not found.", MsgBoxStyle.OkOnly, "File Find Error")
End
End If
我希望这可以帮助别人,因为我已经搜索了一周了!