命名范围的类 – Excel VBA

我正在不断更新和改进一个由Excel创build的财务模型,其中启用了VBAmacros,这个macros被多个人主动使用。 首先,这些模板被用作不同项目的预算,所以有很多创build的时间,而较老的预算被重新访问。

我是模板的“守护者”,而其他用户只是使用该文档。 无论何时我需要向每个人推送更新,都会产生问题,因为他们已经在模板的较早版本中创build了预算,并且在新模板中重新创build预算需要花费过多的时间。

我已经通过命名范围在较小规模的模板上解决了这个问题,然后将这些命名范围应用于旧版本,然后使用命名范围将其复制到新版本模板中相同的命名范围中。 但是,这是通过单独的代码行来复制每个命名的范围。

有没有办法将一组命名范围聚合到一个类中,以便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所有GroupClass

我将在您的模板中创build一个新的工作表,列出所有这些命名的范围; 从VBA读取列表并循环访问它们。

如果VBA中存在MVC模式,则命名范围可以表示一个View对象。
我个人有一些MV *模式的经验,其中视图也实现事件(通常委派给控制器对象)。

使用这种方法的好处是,您将以更加模块化的方式开始编程。

我在下面提供一个例子:

简单命名范围“persons”的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 

您可以在类构造函数中定义私有的pRange属性。

导致Excel出错的一个原因是,事先并不知道范围的大小,以及错误发生的事实,比如上一次没有正确清理的范围。
这就是为什么重要的是还要定义以下属性:

  • _oRange作为Excel.Range
  • _snamed_range作为string;
  • _lNr_rows一样长;
  • _iNr_cols为整数;
  • _iOffset_x只要;
  • _lOffset_y为整数;
  • oCollection作为集合(你也可以使用这个字典)

注意:oCollection是一个由不同的cls_view_persons实例组成的对象;

和方法:

  • 初始化:类构造函数:定义一个默认的范围对象,或者如果你愿意的话,你可以在创build时传递一个范围;
  • get_named_range:返回一个范围对象;
  • set_named_range:设置范围对象属性并在表单对象中创build命名的范围;
  • collection_to_array:将集合对象转换为数组;
  • clear_range:清除范围;
  • 一种使用前三种方法的render方法,并将创build的数组中的数据写入一个语句中的范围:

    set pRange = vPersons

vPersons是一个数组,包含不同的人(见后面)。

  • (从范围读取的“读取”方法也是有用的)。

    2人模特(例子)

模型表示应用程序的数据逻辑,并且本身不一定与某个特定视图相关。 在这种情况下,它是,但模型(或模型集合)原则上是独立的)。
人员模型可以是定义以下属性的类:

  • 名字
  • 地址
  • 国家

无论是从数据库,从一个Excel工作表(后者是最糟糕的情况,这不幸发生最多)或任何其他来源提取这些模型。

不pipe你做什么,你都需要看到你最终得到一个可以提供给View对象的Collection对象。
一旦完成,View对象应该自己pipe理。 从那一刻起,所有的解释和渲染都被委托给这个对象。
意即:

  • validation尺寸;
  • 清除以前的结果;
  • 在屏幕上渲染范围(即设置新维度,在工作表中创build命名范围,将集合转换为数组,并将数组写入屏幕)。

您会看到这种方法在以下方面有很多好处:

  • 保养;
  • 更less的错误;
  • 模块化(和可转移)/封装的属性/方法;
  • dynamic适应性;
  • 你可以从任何数据源读取,如果你只写一个中介“翻译”模块。

我经常通过以下方式从名称检索数据

Workbook.Names包含所有的Name对象,每个Name对象的属性

 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