2012-01-26 62 views
0

我有一個VBA模板項目,當Word文檔打開時自動運行。但是,如果我打開多個文檔,它們都共享變量值。如何聲明這些變量只與活動窗口或活動文檔相關聯?如何防止在Word文檔中共享VBA變量?

我試着在類模塊中聲明它們,但是沒有幫助。在打開的文檔之間切換我可以看到這些變量是共享的。

任何輸入讚賞...

這是我在我的模塊:

Option Private Module 
    Dim CurrentCommand As String 

    Public Function SetCurrentCommand(command) 
    CurrentCommand = command 
    End Function 

    Public Function GetCurrentCommand() 
    GetCurrentCommand = CurrentCommand 
    End Function 

更多信息:代碼/宏開始在AutoExec的是這樣的:

Public Sub Main()  
    Set oAppClass.oApp = Word.Application 
    If PollingRate <> "" Then Application.OnTime Now + TimeValue(PollingRate), "CaptureUserViewState" 
End Sub 

而CaptureUserViewState是一個Sub,它駐留在一個不同的模塊中,並執行所有的檢查(比較新值和最後記錄的),他重新此子如何做的檢查:

If WL_GetterAndSetter.GetLastPageVerticalPercentage <> pageVerticalPercentScrolled Then 
    'Update the last value variable 
    WL_GetterAndSetter.SetLastPageVerticalPercentage (pageVerticalPercentScrolled) 
    'log change 
End If 
+0

請向我們展示如何在首位聲明這些變量。 –

回答

3

你不給我們太多的信息,但我想你宣佈在模塊級這樣的公共變量:

Public myString As String 
Public myDouble As Double 

從VBA文檔:

變量使用Public語句聲明是適用於所有模塊中的所有過程中的所有應用程序除非Option Private Module是效果;在這種情況下,變量只在它們所在的項目中公開。

答案是使用Option Private Module

當在允許跨多個項目引用的主機應用程序中使用時,Option Private Module可防止在其項目之外引用模塊內容。

[...]如果使用了,Option Private語句必須出現在模塊級別,在任何過程之前。

編輯您現在已經澄清,聲明在模塊級使用Dim您的變量。在這種情況下,Option Private Module是無關緊要的。

在模塊級別聲明爲Dim的變量可用於模塊中的所有過程。

即無論您是否使用Option Private Module

如果您發現這些值在運行之間保留,那必須是因爲您正在從同一工作簿的相同模塊運行一個過程。你可能認爲你在做別的事情,但實際上這就是你正在做的事情。

編輯

在你的類模塊,而不是Dim CurrentCommand As String嘗試Private CurrentCommand As String。沒有更多的信息,很難調試你的程序。我只是在這裏隨機拍攝。

+0

使用Option Private Module不能解決問題。該模塊中的變量仍然在Word文檔中共享。 – Alaa

+0

@Alaa:他們在類模塊還是常規模塊中聲明?你怎麼知道他們正在共享? –

+0

我嘗試了課堂和常規模塊。讓我解釋一下,我跟蹤垂直滾動位置,並記錄最後一個位置。讓我們說文檔A和B被打開。當我向下滾動文檔A時,顯示帶有最後和當前垂直滾動位置的MsgBox。現在讓我們說,值是(最後位置:0 - 當前位置:7)。現在我移動到文檔B.雖然我沒有在文檔B中滾動,所以MsgBox將顯示顯示(最後一個位置:7 - 當前位置:0),因此它最後的當前滾動位置應該爲0. – Alaa

0

您需要做的是存儲多個版本的變量,每個文檔一個集合。 所以我建議你創建一個簡單的類來保存不同的值。 然後,您將它們存儲在映射數據集的文件集名稱或類似密鑰的集合中。

在classmodule(邁德特),標記爲市民:

Public data1 as String 
Public data2 as Integer 

與事件處理模塊:

Dim c as new Collection 'module global declaration 

Sub AddData() 
    Dim d as new MyData 'Your data set 
    d.data1 = "Some value" 
    d.data2 = 42 
    c.add Value:=d, Key:=ActiveDocument.name 
End Sub 

然後,當你進入事件處理程序中檢索數據和使用當前活動文檔的特定集合。

Sub EventHandler() 
    Dim d as MyData 
    set d = c.item(ActiveDocument.name) 
    'use data 
    'd.data1... 
End Sub 

請注意,這段代碼只是在概念層面。它不工作,你必須將它應用於你的問題,但它應該給你一些你需要做的想法。您需要添加很多錯誤處理,檢查項目是否已經在集合中等等,但是我希望您瞭解這個概念,以便繼續嘗試。

之所以這樣做,是因爲根據您的問題了解情況,您只能運行腳本的一個版本,但只能運行多個文檔。因此腳本必須知道所有不同的文檔。另一方面,如果每個文檔都有它們自己的代碼/事件處理程序,因此有多個版本的腳本在運行,那麼你不需要上面提供的解決方案。相反,您需要小心在腳本中引用的文檔實例。通過始終使用「ThisDocument」而不是「ActiveDocument」,如果將代碼放置在每個打開的文檔中,您可以實現隔離。

但是,據我瞭解,您只有一個版本的腳本運行,與打開的文檔分開,因此第一個解決方案適用。

祝你好運!

0

您可能希望存儲使用 的Document.CustomDocumentProperties物業 http://msdn.microsoft.com/en-us/library/office/aa212718(v=office.11).aspx

這會返回一個 DocumentProperties集合 ,您可以添加新的屬性,以使用

Document.CustomDocumentProperties.Add(PropertyName, LinkToContent, Value, Type) 

,然後將文檔的具體細節閱讀使用

Document.CustomDocumentProperties.Item(PropertyName) 

這裏的缺點或者獎勵是,除非刪除它們,否則屬性將保留在文檔中。

這可能是件好事或壞事