[英]Class of Named Ranges - Excel VBA
I am in the process of continuously updating and improving a financial model built in Excel with VBA macros enabled that is in active use by multiple people. 我正在不断更新和改进在Excel中启用的VBA宏构建的财务模型,该模型已被多个人积极使用。 Primarily, these templates are used as budgets for different projects, so there are many created all the time while older budgets are re-visited.
最初,这些模板用作不同项目的预算,因此在重新访问较旧的预算时,总是会创建许多模板。
I am the "keeper" of the template while the other users simply use the document. 我是模板的“管理员”,而其他用户只是使用该文档。 Whenever I need to push out an update to everyone, it creates an issue because they already have created the budget in an older version of the template and to re-create the budget in the new template would take an inordinate amount of time.
每当我需要向所有人推送更新时,都会造成问题,因为他们已经在模板的较旧版本中创建了预算,而在新模板中重新创建预算将花费大量时间。
I have gotten around this problem on smaller-scale templates by naming ranges and then applying those named ranges to an old version and then using the named ranges to copy into the same named range in the new version of the template. 我已经在较小规模的模板上解决了此问题,方法是命名范围,然后将这些命名范围应用于旧版本,然后使用命名范围复制到模板的新版本中的相同命名范围中。 However, this was done with individual lines of code to copy each named range.
但是,这是通过单独的代码行复制每个命名范围来完成的。
Is there a way to aggregate a group of named ranges into a class so that Excel can just loop through all of the items in the class and copy the data rather than me needing to code out each line to perform a copy? 有没有一种方法可以将一组命名范围聚合到一个类中,以便Excel可以循环遍历该类中的所有项目并复制数据,而不需要我编写每行代码以执行复制?
Here is a sample of the code that I am currently running: 这是我当前正在运行的代码示例:
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
There are dozen of more lines of code similar to this for each named range. 每个命名范围都有十几行与此类似的代码行。 Inside the template, the ranges refer to lists of names of staff, ID numbers, hours worked, etc. and they also span multiple sheets within the workbook with each range of different size.
在模板内部,范围是指职员姓名,ID号,工作时间等的列表,它们还跨越工作簿中的多个工作表,每个范围的大小各不相同。
I am wondering if there is some sort of class that I could place in front of each named range when I define it so that they are treated as a class together and can be looped through. 我想知道在定义它时是否可以在每个命名范围的前面放置某种类,以便将它们一起视为一个类并可以循环通过。 For example:
例如:
Office_Employee_Names
becomes 变成
GroupClass.Office_Employee_Names
Then the code could loop through everything in GroupClass
然后代码可以遍历
GroupClass
所有GroupClass
IF an MVC pattern would exist in VBA, then a named range could represent a View object. 如果VBA中将存在MVC模式,则命名范围可以表示View对象。
I personally have some experience with an MV* pattern where Views also implement events (which are normally delegated to Controller objects). 我个人对MV *模式有一些经验,在该模式中,视图还实现了事件(通常将事件委托给Controller对象)。
The benefit of using this approach, is that you will start programming in a much more modular fashion. 使用这种方法的好处是,您将以更加模块化的方式开始编程。
I provide an example below: 我在下面提供一个示例:
The structure of an MV* implementation of a simple named range "persons" could have the following class structure: 简单命名范围“人”的MV *实现的结构可以具有以下类结构:
Imagine that cls_view_persons
represents a view object, then this would mean that you have to instantiate it from a base sub, which will simply be: 假设
cls_view_persons
代表一个视图对象,那么这意味着您必须从基础子实例化它,该子类将简单地是:
dim view_persons as cls_view_persons
set cls_view_persons = new cls_view_persons
1. persons view (example) 1.人员视图(示例)
The cls_view_persons class will have a property that defines the range of the class. cls_view_persons类将具有定义该类范围的属性。 For example:
例如:
private pRange as new Range
You can define the private pRange property in the class constructor. 您可以在类构造函数中定义private pRange属性。
One of the things that makes Excel buggy, is the fact that you don't know in advance the size of the range, and the fact that mistakes happen, such as a range that was not properly cleared the last time. 导致Excel出现错误的原因之一是您不预先知道范围的大小,并且发生了错误(例如上次未正确清除的范围)这一事实。
This is why it is important to also define the following properties: 这就是为什么还要定义以下属性很重要的原因:
Note: oCollection is an object that will consist of the different cls_view_persons instances; 注意:oCollection是一个将由不同的cls_view_persons实例组成的对象。
and methods: 和方法:
A render
method that uses the previous three methods and writes data from the created array to the range in a single statement: 一个
render
方法,该方法使用前三种方法,并在单个语句中将创建的数组中的数据写入范围:
set pRange = vPersons
Where vPersons is an array, containing the different persons (see later). vPersons是一个数组,其中包含不同的人(请参阅下文)。
(A "read" method that reads from the range would be useful as well). (从该范围读取的“读取”方法也将很有用)。
2 person model (example) 2人模型(示例)
A model represents the data logic of your application and is on itself, not necessarily related to one specific view. 模型代表您的应用程序的数据逻辑,并且自身存在,不一定与一个特定的视图相关。 In this case it is, but a model (or Collection of models) is in principle independent).
在这种情况下,是这样,但是模型(或模型集合)原则上是独立的。
A person model could be a class that defines the following properties: 人员模型可以是定义以下属性的类:
Either these models are fetched from a database, from an Excel sheet (the latter being the worst scenario, which unfortunately happens the most) or any other source. 这些模型可以从数据库,Excel工作表(后者是最坏的情况,不幸的是发生最多的情况)或任何其他来源中获取。
Whatever you do, you need to see that you end up with a Collection object that you can feed to the View object. 无论您做什么,都需要确保最终得到一个Collection对象,您可以将其提供给View对象。
Once this is done, the View object should manage its own. 完成此操作后,View对象应自行管理。 All interpreting and rendering is delegated to this object from that moment on.
从那时起,所有解释和渲染都委托给该对象。
This means: 这意味着:
You will see that this approach has many benefits in terms of: 您将看到此方法在以下方面有很多好处:
I would create a new worksheet in your template that list all these named ranges; 我将在您的模板中创建一个新的工作表,其中列出了所有这些命名范围; read the list from VBA and loop through them.
从VBA中读取列表,然后遍历它们。
I often retrieve data from Names by: 我经常通过以下方式从“名称”中检索数据:
Workbook.Names contains all Name Objects, and each Name Object its properties 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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.