2011-10-07 208 views
2

首先:我正在使用Excel 2007,但代碼也必須適用於Excel 2003。Excel VBA無法打開工作簿

我的問題如下:我需要訪問不同工作簿中的單元格,這可能會被關閉。下面的代碼可以在整個網絡上找到:

Function Foo() 
    Dim cell As Range 
    Dim wbk As Workbook 
    Set wbk = Workbooks.Open("correct absolute path") 
    ' wbk is Nothing here so the next statement fails. 
    Set cell = wbk.Worksheets("Sheet1").Range("A1") 
    Foo = cell.Value 
    wbk.Close 
End Function 

可悲的是,WBK是開放的語句之後沒有什麼(我很樂意提供更好的錯誤消息,但不知道我怎麼會做什麼;什麼我會給一個真正的IDE和一個有用的語言:/)。絕對路徑是正確的並且指向一個有效的excel xlsx文件。

另外我假設這樣做的最好方法是「緩存」工作簿,而不是每次調用函數時打開/關閉它?任何可能出現的問題(除了在工作簿已經打開時必須處理這種情況)?

圖像,同時通過加強: debugging info

+0

您不會收到錯誤消息,並且「Open」語句只返回Nothing?我試過重試你的問題失敗了。你將不得不給我們更多的細節和上下文。 –

+0

@ Jean-FrançoisCorbett要說「不」,錯誤信息就是說,excel只是繼續執行。我看了一下,但找不到任何'GetLastError()'或類似的'On Error Goto'沒有指定任何異常對象?引用的東西基本上是整個功能,但我將其改爲完整的功能,可能有幫助。 – Voo

+0

立即窗口中的「?Err.Number」和「?Err.Description」將爲您提供有關運行時錯誤的信息。您需要爲On Error Goto提供錯誤處理程序。當你說「下一個語句失敗」時,你的意思是你在那裏得到一個運行時錯誤?如果是這樣,什麼?如果不是,Cell是否也等於沒有?您是否嘗試過一個非常簡單的路徑,例如,「我的文檔」中的文件? –

回答

5

我可以重現此問題。它只發生在我嘗試將這些代碼粘貼到用戶定義的函數中。

我相信這是由設計(報價是2003 XL,但同樣的事情發生在我身上的2010 XL)

使用VBA的關鍵字,自定義函數

VBA的關鍵字數量您可以在自定義函數中使用比在宏中可以使用的數量更小的值。除了向工作表中的公式或另一個VBA宏或函數中使用的表達式返回值之外,自定義函數不允許執行任何操作。例如,自定義函數無法調整窗口大小,編輯單元格中的公式,或更改單元格中文本的字體,顏色或圖案選項。如果在一個函數過程中包含這種「動作」代碼,函數將返回#VALUE!錯誤。

http://office.microsoft.com/en-us/excel-help/creating-custom-functions-HA001111701.aspx

我發現的唯一的解決方法是通過正常的宏調用這種代碼。就像選擇單元格來應用它,然後循環選擇或類似的東西。

+0

謝謝你,是的,這就是我也在做的事情,只是沒有認爲它很重要(當然,我並沒有意識到自己在做一些不同的事情)。 – Voo

1

若要從工作簿中獲取數據,而無需打開時,您可以使用this,用ADO連接。

要在Excel 2007中改變使用

Microsoft.Jet.OLEDB.4.0 

Provider=Microsoft.ACE.OLEDB.12.0 

Extended Properties=\"Excel 8.0;HDR=Yes;\ 

Extended Properties=\"Excel 12.0;HDR=Yes;\ 

[]的

0

你不必「設置」一個單元格,它是工作簿類的一部分(據我所知)。只需使用以下...

foo = wbk.Worksheets("Sheet1").Range("A1").Value 
+0

單元不是任何類的一部分。這是一個被聲明爲範圍的變量,所以它必須被設置。也許你正在考慮作爲Worksheet對象屬性的「單元格」。您的建議確實縮短了代碼,但並未解決問題。 -1 –

+0

是的,我可以重寫所有東西以適合一行 - 如果我開始用1個字符來命名變量,我甚至可能進入Perl程序員俱樂部,但是,這實際上不是總體目標;) – Voo

+0

你是對的,我忽略了我的答案。但回頭再試一試現在就可以運行。嗯,也許發佈我們你的(「正確的絕對路徑」)?如果可能的話。因爲否則你的代碼工作正常.. – TheFuzzyGiggler

0

我建議您在打開調用工作簿時在worbook_open事件中爲您打開新工作簿。

然後,您將新工作簿參考存儲在全局變量中。

然後,您的單元調用的函數使用上述全局變量而不是嘗試打開新的工作簿。這樣你可以繞過這個限制。 PS:當然要避免全局變量,某種容器比直接的全局變量要好。

1

將我的例程放入工作簿模塊中的單獨宏並從Workbook_BeforeSave代碼中調用該宏的解決方法似乎已經完成。

我有類似的問題,但在我的情況下,它是一個「Workbooks.Open(文件名)」命令在嵌入Workbook_BeforeSave的小例程開始。 VBA只是跳過代碼行,就好像它不在那裏,它甚至不報告Err.Code或Err.Description。

對我來說唯一的線索是它是Workbook_BeforeSave例程的一部分,上面的函數的限制似乎表明可能是一個可能的原因。所以我進一步挖掘以找到更多細節。

Workbook_BeforeSave似乎禁止Excel打開更多文件,我猜這樣做很好,因爲文件>打開選項在文件菜單中仍然可見,但無法單擊。奇怪的是,打開工具欄圖標/按鈕仍然有效,所以雖然我可以從那裏手動打開文件,但是我不知道是不是因爲從VBA代碼調用這個動作是不可能的,這就是爲什麼他們允許它?

1

你可以使用這個(類似於布魯諾·雷特提出,但要簡單得多寫):

Dim excelApp As New Excel.Application 
excelApp.Visible = False 
Set WB = excelApp.Workbooks.Open(FileName, xlUpdateLinksNever, True) 

由於UDF是一再呼籲,應該確保做一個excelApp.Quit退出函數之前(以及之前的WB.close(False)),以避免在您的盒子上運行無數Excel實例。

我花了一些想法,並得出結論,您不能在執行UDF時混淆當前Excel實例的工作簿。另一方面,打開excel的第二個例子將在不受干擾的情況下完成工作。

+0

但是...如果您必須重複使用UDF,速度非常慢。 – Javi