如何使用 OLE 检查文件是否在 Excel 中打开(使 Excel 进程保持打开状态)

发布于 2024-12-01 07:53:35 字数 2213 浏览 1 评论 0 原文

如何检查文件是否已在某些 Excel 实例中打开?

我使用 DXL (DOORS) 语言,但它应该独立于该语言。

是否有任何 OLE 方法可以调用来检查打开了哪个文件并将其与路径/文件名进行比较?

如果可能的话,我可以只关闭该 Excel 应用程序中的工作表/文件吗?

编辑: 这就是我到目前为止所得到的,这有效但只能一次。 DXL 使 Excel.exe 进程保持打开状态,并在接下来的检查中检查所使用的实例是否没有打开的工作簿,甚至根本没有窗口。

        if (confirm "File \"" fPath "\" already exists. Do you want to overwrite it?") {

        // check if file is opened in any Excel instance
        OleAutoObj oleWorkbooks     = null;
        OleAutoObj oleExcel         = null;
        OleAutoObj oleWorkbook      = null;
        OleAutoArgs autoArgs = create;

        oleExcel = oleGetAutoObject("Excel.Application");
        bool opened = false;
        // if excel is opened
        if(oleExcel != null){
            d("Excel is opened");
            // Get workbooks and open file
            oleGet(oleExcel,"Workbooks", oleWorkbooks);

            // compare each open workbook
            int count = 0;
            oleGet(oleWorkbooks,"Count", count);
            string workbookname = "";
            string sPath = replace(fPath, "\\", "/");
            sPath = stripPath(sPath, true);

            while (count > 0) {
                d("checking opened document");
                clear(autoArgs);
                put(autoArgs, count);
                oleGet(oleWorkbooks,"Item", autoArgs, oleWorkbook);
                oleGet(oleWorkbook, "Name", workbookname);
                opened = sPath == workbookname;
                if(opened) {
                    if(confirm "The file is currently opened in Excel. It must be closed. Do you want to close the document?") {
                        clear(autoArgs);
                        oleMethod(oleWorkbook,"Close",autoArgs);
                    }
                    break;  
                }
                count--;
            }
        }
        oleCloseAutoObject(oleExcel);
        oleCloseAutoObject(oleWorkbooks);
        oleCloseAutoObject(oleWorkbook);
        // todo leaves excel process open

        if(!opened) {
            streamOutputData = write fPath;
            streamOutputData << sOutput;
            close streamOutputData;
            return true;    
        }
    }

how may I check if a file is already opened in some Excel instance?

I use DXL (DOORS) language but it should be independent from this language.

Is there any OLE method that I can call to check which file is opened and compare that with the path/filename?

and if that is possible, can I close only that worksheet/file in that Excel application?

edit:
this is what I got till now, this works but only once. DXL leaves an Excel.exe process open and in next checks that instance is used which has no open workbooks or even no window at all.

        if (confirm "File \"" fPath "\" already exists. Do you want to overwrite it?") {

        // check if file is opened in any Excel instance
        OleAutoObj oleWorkbooks     = null;
        OleAutoObj oleExcel         = null;
        OleAutoObj oleWorkbook      = null;
        OleAutoArgs autoArgs = create;

        oleExcel = oleGetAutoObject("Excel.Application");
        bool opened = false;
        // if excel is opened
        if(oleExcel != null){
            d("Excel is opened");
            // Get workbooks and open file
            oleGet(oleExcel,"Workbooks", oleWorkbooks);

            // compare each open workbook
            int count = 0;
            oleGet(oleWorkbooks,"Count", count);
            string workbookname = "";
            string sPath = replace(fPath, "\\", "/");
            sPath = stripPath(sPath, true);

            while (count > 0) {
                d("checking opened document");
                clear(autoArgs);
                put(autoArgs, count);
                oleGet(oleWorkbooks,"Item", autoArgs, oleWorkbook);
                oleGet(oleWorkbook, "Name", workbookname);
                opened = sPath == workbookname;
                if(opened) {
                    if(confirm "The file is currently opened in Excel. It must be closed. Do you want to close the document?") {
                        clear(autoArgs);
                        oleMethod(oleWorkbook,"Close",autoArgs);
                    }
                    break;  
                }
                count--;
            }
        }
        oleCloseAutoObject(oleExcel);
        oleCloseAutoObject(oleWorkbooks);
        oleCloseAutoObject(oleWorkbook);
        // todo leaves excel process open

        if(!opened) {
            streamOutputData = write fPath;
            streamOutputData << sOutput;
            close streamOutputData;
            return true;    
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧伤慢歌 2024-12-08 07:53:35

使用现有的 DXL 方法 canOpenFile(string path, bool write) 解决了这个问题:

if (confirm "File \"" fPath "\" already exists. Do you want to overwrite it?") {
        if(canOpenFile(fPath, true)) {
            streamOutputData = write fPath;
            streamOutputData << sOutput;
            close streamOutputData;
            return true;    
        }
        else {
            e("File \"" fPath "\" is opened in another program. Close it! (It's probably Excel ;) )");
        }
    }

solved it using existing DXL method canOpenFile(string path, bool write):

if (confirm "File \"" fPath "\" already exists. Do you want to overwrite it?") {
        if(canOpenFile(fPath, true)) {
            streamOutputData = write fPath;
            streamOutputData << sOutput;
            close streamOutputData;
            return true;    
        }
        else {
            e("File \"" fPath "\" is opened in another program. Close it! (It's probably Excel ;) )");
        }
    }
迷途知返 2024-12-08 07:53:35

我不知道 DXL,但这就是您可以在 VBA 中执行的操作,我让您将其调整为 DXL:

Sub IsXLBookOpen(strName As String) 

     'Procedure designed to test if a specific Excel
     'workbook is open or not.

    Dim i As Long, XLAppFx As Excel.Application 

     'Find/create an Excel instance
    On Error Resume Next 
    Set XLAppFx = GetObject(, "Excel.Application") 
    If Err.Number = 429 Then 
        Set XLAppFx = CreateObject("Excel.Application") 
        Err.Clear 
    End If 
    On Error GoTo 0

     'Loop through all open workbooks in such instance
    For i = 1 To XLAppFx.Workbooks.Count
        If XLAppFx.Workbooks(i).Name = strName Then
           MsgBox("The workbook is open")
           'Close the workbook and ask if user wants to save
           XLAppFx.Workbooks(i).Close
           'Force close and save changes
           XLAppFx.Workbooks(i).Close True
    Next i 
End Sub

改编自 这里

I don't know DXL but this is what you could do in VBA, I let you adapt it to DXL:

Sub IsXLBookOpen(strName As String) 

     'Procedure designed to test if a specific Excel
     'workbook is open or not.

    Dim i As Long, XLAppFx As Excel.Application 

     'Find/create an Excel instance
    On Error Resume Next 
    Set XLAppFx = GetObject(, "Excel.Application") 
    If Err.Number = 429 Then 
        Set XLAppFx = CreateObject("Excel.Application") 
        Err.Clear 
    End If 
    On Error GoTo 0

     'Loop through all open workbooks in such instance
    For i = 1 To XLAppFx.Workbooks.Count
        If XLAppFx.Workbooks(i).Name = strName Then
           MsgBox("The workbook is open")
           'Close the workbook and ask if user wants to save
           XLAppFx.Workbooks(i).Close
           'Force close and save changes
           XLAppFx.Workbooks(i).Close True
    Next i 
End Sub

Adapted from here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文