簡體   English   中英

更改Excel單元格時調用自定義的內置VBA函數

[英]Calling a custom built VBA function when an Excel cell is changed

我想通過說我是大學本科生來開頭這個問題,他知道C ++,並且對VBA有非常初步的了解。

然后,如標題中所述,我需要一些幫助來為Excel工作表配置一些VBA代碼,以便每當修改列(特別是D列)中的單元格時,它將自動更新同一行中的其他單元格。

從本質上講,我希望這樣做,以便當用戶Bob修改單元格D26(例如)時,它將調用我構建的自定義函數,並將該代碼插入單元格B26中,然后對單元格C26重復使用其他函數。

但是,此功能必須這樣,如果修改單元格D27,它將僅修改第27行中的其他單元格,而將第26行以及之前或之后的行保留為單獨狀態,直到在D28中調用此函數之時,依此類推。

我不確定這是否可能,但是如果有人可以幫助我進行配置,我會很感激。

我為自定義功能從互聯網上構建/清除的代碼是: http : //pastebin.com/RE0V2nrT

我要為此項目調用的第二個函數是Excel中內置的= TODAY()函數。

到目前為止,我為檢查單元格是否已更改而拼湊的代碼是: http : //pastebin.com/S5E8cmty

如果有人可以幫助我理解如何寫我想要的東西,將不勝感激。 如果您有其他解決問題的方法,我也很想聽聽...只要您能幫助我然后制定解決方案,哈哈!

無論如何,感謝任何回復的人。

看一下Excel命名空間中可用的工作表事件 為此,您將使用Change事件

如果雙擊要監視的工作表,則可以插入Worksheet_Change子項。 然后,您可以使用相交功能檢查更改后的單元格是否在您要監視的范圍內(例如D:D)。

您可以指定要更改的單元格。 在這里,我僅根據您的要求給出一個示例。 這會將函數的輸出放入單元格B [R]中,並將當前日期放入單元格C [R]中。 請注意,由於VBA中沒有Today()函數,因此我正在使用Now()函數。 由於這會同時返回日期和時間,因此我正在使用Format函數來獲取日期。

只是為了好玩,讓我們進一步深入對象模型,並首先獲取目標范圍所屬的Worksheet對象 這不是100%必需的-您可以僅依賴ActiveSheet 現在,您可能不需要執行此操作,而這主要只是為了好玩,但還需要注意的是,如果您是通過編程方式對此工作表進行更改,但沒有首先激活此工作表(因此另一個工作表處於活動狀態),並且您沒有關閉EnableEvents就會得到一些奇怪的結果:)

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim TargetSheet As Worksheet
    Set TargetSheet = Target.Parent
    With TargetSheet
        If Not Application.Intersect(Target, .Range("D:D")) Is Nothing Then
            .Cells(Target.Row, 2) = ExtractWindowsUser()
            .Cells(Target.Row, 4) = Format(Now(), "YYYY-MM-DD")
        End If
    End With

End Sub

說明

像這樣聲明工作表更改子。 Worksheet對象具有事件的預定義方法存根。 有點像接口,盡管未在文檔中列為接口。 如果您以這個概念來考慮,這就是您的事件握手。 請參閱我上面發布的鏈接,以獲取可用的工作表事件列表。
Private Sub Worksheet_Change(ByVal Target As Range)

在接下來的幾行中,我們將獲取名為Target的對象所屬的工作表對象。 您可以在子聲明中看到Target被聲明為Range類型的對象。 如果您查看工作表對象(如上鏈接)或范圍對象文檔,您會看到范圍對象是工作表對象的成員,並且文檔類型很爛,但是僅供參考,工作表對象包含在對象中財產 現在,最初,我使用Application對象的ActiveSheet成員使用我的代碼-但由於上面我的回答中給出的原因,我已經對其進行了編輯。

Dim TargetSheet As Worksheet
Set TargetSheet = Target.Parent

我使用With Blocks保存在多個地方鍵入相同的工作表引用。 With塊僅允許我通過輸入.SomeMember訪問指定的名稱空間的成員(在這種情況下為對象TargetSheet成員)。 編譯器理解,每個這樣的引用都引用開頭的With ....語句中指定的任何內容。 我個人喜歡這樣做,以提高可讀性,但我也建議將其用於維護(將參考位置更改為多個)。 同樣,只有一個引用會帶來微不足道的微不足道的效果,也許不值得一提。

With TargetSheet

接下來,我們檢查Target是否在我們要觀看的單元格范圍內。 If....Then應該看起來足夠熟悉。 對於我們的條件,我們使用布爾運算符Not來檢查相交函數(上面鏈接)的結果是否為Nothing 我們這樣做的原因是檢查是否分配了退貨。 如果分配了對象,則“ Not SomeObject Is Nothing條件的結果將為False 如果未分配對象(即,我們的Intersect函數未能返回任何內容),則該語句的值為True 因此,從“相交”功能文檔中我們知道,如果分配了返回值,則范圍相交,並且返回相交的范圍對象。 因此,如果我們想知道它們是否相交,我們可以檢查是否存在故障。

If Not Application.Intersect(Target, .Range("D:D")) Is Nothing Then

然后,接下來的幾行只需在與Target行相同的單元格上執行一些代碼即可。 我們使用工作表對象的Cells成員來指定要修改的單元格。 根據文檔, Cells的默認屬性是Item ,它使我們可以通過行和列索引訪問范圍對象,如下所示: .Cells[Row,Column] 因此,我只使用Target對象的行和所需的列(列“ A” = 1,“ B” = 2,依此類推。如果有興趣,可以通過將excel屬性更改為R1C1引用樣式來查看)。

.Cells(Target.Row, 2) = ExtractWindowsUser()

而且我認為Format()和Now()函數在文檔中作了很好的解釋。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM