2014-02-25 65 views
0

我在不斷更新和改善內置Excel中使用VBA宏財務模型的過程中啓用的是由多人運行。首先,這些模板被用作不同項目的預算,所以有很多時候都會創建這些模板,而較老的預算會被重新訪問。類命名區域 - Excel的VBA

我的模板的「守護者」,而其他用戶只需使用的文檔。無論何時我需要向每個人推送更新時,都會產生問題,因爲他們已經在較早版本的模板中創建了預算,並且在新模板中重新創建預算需要花費過多的時間。

我已經通過命名範圍,然後將這些命名範圍應用到舊版本,然後使用命名範圍複製到新版本模板中相同的命名範圍,在小範圍模板上解決了此問題。但是,這是通過單獨的代碼行來複制每個命名範圍。

有沒有辦法將一組命名區域聚合到一個類中,以便Excel可以循環遍歷類中的所有項並複製數據,而不是我需要編寫每行來執行復制?

這裏是我當前正在運行的代碼示例:

Workbooks(WB_Active_Name).Sheets("Office Staff Input").Range("Office_Employee_Names").Value = Workbooks(WB_Secondary_Name).Sheets("Office Staff Input").Range("Office_Employee_Names").Value 
    Workbooks(WB_Active_Name).Sheets("Office Staff Input").Range("Office_Employee_Positions").Value = Workbooks(WB_Secondary_Name).Sheets("Office Staff Input").Range("Office_Employee_Positions").Value 
    Workbooks(WB_Active_Name).Sheets("Office Staff Input").Range("Office_Employee_Numbers").Value = Workbooks(WB_Secondary_Name).Sheets("Office Staff Input").Range("Office_Employee_Numbers").Value 
    Workbooks(WB_Active_Name).Sheets("Office Staff Input").Range("Office_Employee_Bonus_Sharing").Value = Workbooks(WB_Secondary_Name).Sheets("Office Staff Input").Range("Office_Employee_Bonus_Sharing").Value 

還有的多行代碼類似於這樣每個命名範圍打。在模板內部,範圍是指工作人員姓名,身份證號碼,工作時間等列表,並且它們還跨越工作簿中的多個工作表,每個工作簿的大小都不同。

我想知道是否有某種類的,我可以在每個命名範圍的前面放置時,我把它定義使他們作爲一個階級一起處理,並可通過環接的。例如:

Office_Employee_Names 

成爲

GroupClass.Office_Employee_Names 

然後代碼可以通過一切GroupClass

+2

證明你目前如何做。顯示一些代碼,我們將幫助你改進它。同樣,你談論的東西的視覺示例也不會受到傷害,因爲很難想象出某些模板。 – 2014-02-25 15:30:25

+0

你是否想要維護一個所有範圍的列表作爲你可以循環的東西?如果是這樣,你可以做到這一點......創建一個過程,該過程定義了一個包含所有命名範圍的字符串數組。然後,你總是可以根據需要添加新元素到數組中,並在你的代碼中引用該數組......我不理解你的問題嗎? –

+0

使用示例代碼查看我對上面原始帖子的編輯。 – Michael

回答

1

我會在您的模板中創建一個新的工作表,列出所有這些命名範圍;從VBA讀取列表並循環訪問它們。

+0

+1我的最愛,最簡單的解決方案 –

+0

確實是一個很好的解決方案。我是否需要引用命名範圍所在的工作表名稱?出於某種原因,它似乎給我提供了一些問題,儘管我認爲Excel可以在工作簿中找到指定的範圍。 – Michael

1

循環,如果一個MVC模式將存在於VBA,然後命名範圍可以代表查看目的。
我個人有一些MV *模式的經驗,其中Views也實現事件(通常委派給Controller對象)。

使用這種方法的好處是,你將在一個更加模塊化的方式開始編程。

我在下面提供一個例子:

的MV的結構*實現一個簡單的命名範圍的 「人」 可能有下面的類結構:

  • cls_view_persons
  • cls_model_person

想象一下,cls_view_persons代表一個視圖對象,那麼這意味着你必須從一個基本子實例化它,這將簡單地是:

dim view_persons as cls_view_persons 
set cls_view_persons = new cls_view_persons 

1.人查看(例如)

的cls_view_persons類將具有定義的類的範圍的特性。 例如:

private pRange as new Range 

可以定義在類的構造函數的私有財產普蘭奇。

其中一個導致Excel錯誤的原因是事實上,您事先並不知道範圍的大小以及發生錯誤的事實,例如上次沒有正確清除的範圍。
這就是爲什麼它是重要的還定義了以下屬性:

  • _oRange爲Excel。範圍
  • _sNamed_range as string;
  • _lNr_rows as long;
  • _iNr_cols as integer;
  • _iOffset_x只要;
  • _lOffset_y as integer;
  • oCollection作爲收藏(你也可以使用字典這個)

注:oCollection是一個對象,將包括不同cls_view_persons實例;

和方法:

  • 初始化:類構造函數:定義了默認的範圍對象,或者如果你願意的話,你可以通過對創建時間的範圍;
  • get_named_range:返回一個範圍對象;
  • set_named_range:設置範圍對象屬性並在工作表對象中創建命名範圍;
  • collection_to_array:將集合對象轉換爲數組;
  • clear_range:清除範圍;
  • 使用先前的三種方法和從所創建的陣列中的一個語句將數據寫入範圍A render方法:

    set pRange = vPersons

凡vPersons是一個數組,含有不同的人(見後面)。

  • (從該範圍讀取的「讀取」方法也是有用的)。

    2人模型(實施例)

甲模型表示應用程序的數據的邏輯和是在其自身上,不一定與一個特定視圖。在這種情況下,它是,但模型(或模型集合)原則上是獨立的)。
一個人模型可以定義以下屬性的類:

  • 姓氏
  • 地址
  • 國家

無論這些模型是從數據庫中提取,從一個Excel工作表(後者是最糟糕的情況,不幸發生的情況最多)或任何其他來源。

無論你做什麼,你都需要看到你最終得到一個Collection對象,你可以將它提供給View對象。
一旦完成,View對象應該管理它自己的。從那時起,所有的解釋和渲染都被委託給這個對象。
這意味着:

  • 驗證尺寸;
  • 清除之前的結果;
  • 在屏幕上渲染範圍(即設置新尺寸,在工作表中創建指定範圍,將集合轉換爲數組以及將數組寫入屏幕)。

你會看到,這種方法在以下方面有很多好處:

  • 維護;
  • 減少錯誤;
  • 模塊化(和可轉移)/封裝的屬性/方法;
  • 動態適應性;
  • 如果您只編寫中介「翻譯器」模塊,您可以從任何數據源讀取數據。
+0

我意識到這看起來很複雜,但當我告訴你它不是時,請相信我。一旦你習慣了使用MVC或MV *工作流程,你將很快習慣這些慣例,並發現與它合作會更愉快。出於簡單的原因,您將能夠更快速地進行調試(封裝對象),更快地編寫擴展,更容易地查找和解決錯誤(而不是意大利式麪條編碼您的模塊,不知道變化的後果),也許最重要的是,開發可重用的代碼,同時你知道它會使你的對象和方法穩定。 – Trace

+1

你應該添加這個作爲一個問題的規範答案,因爲在這裏它可能得不到許多意見,但是在你自己構思的一個寫得很好的問題上,它可能更有用...... + 1 –

0

我經常檢索由名稱數據:

Workbook.Names包含所有名稱對象,每個名稱對象及其屬性

Dim WBook As Workbook 
Dim WName As Name 

Set WBook = ActiveWorkbook 
For Each WName In WBook.Names 
    Debug.Print WName.Name, WName.RefersToLocal 
Next WName