1

私は数年間 VBA を使用してきましたが、より強力なコーディング手法を利用するために VB に切り替えています。

Excel ワークブックを開いているインスタンスにアタッチする次の VB コードがあります。

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 をプロセスにアタッチできます。

何か案は?これを行う簡単な方法はありますか?

4

2 に答える 2

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

1週間検索したので、これが他の誰かに役立つことを願っています!

于 2012-09-25T03:30:37.707 に答える
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
于 2012-09-24T07:48:46.320 に答える