Вы находитесь на странице: 1из 31

Charting A Mathematical Equation Using Excel And Defined Names

Introduction
When doing mathematics, wouldn't it be nice if we could type an equation into a cell in Excel and immediately see the resulting graph? Suppose we have an equation like: y=x2-2.x+6 Normally, we would create a column with x values and in the adjacent column "translate" this formula into a cell formula: =A2^2-2*A2+6 and copy this formula down to match the number of x values in column A:

Subsequently, we would base a chart on this set of data:

This method lacks flexibility. It would be much more convenient, if we could:


Enter the (any!) formula into a single cell Enter the lower and upper limit of the x-range into two other cells Enter the number of values to use for the chart in yet another cell:

Yet another constraint we're going to place on this task: Apart from the cells shown in the figure above, no cells are to be used, just defined names with formulas.

Create the Chart


Because we cannot start creating a chart without data, simply add some data to a couple of cells:

and click the chart wizard button. Make sure to select the "XY (scatter)" chart type and hit Finish. Now define two names local to the worksheet the chart is on: Name Refers To

Sheet1 $A$12:$A$ !x 15 Sheet1 $B$12:$B$ !y 15 Now we need to use these two defined names in the chart's SERIES formula (click the line in the chart and then click the formula bar), currently looking like this:

(Note this shows the SERIES formula as I see it, with the semicolon as list separator.) Edit this formula so it looks like this: =SERIES(Sheet1!$B$8,Sheet1!x,Sheet1!y,1) Cell B8 will contain the chart's title, so we'll put this little formula in B8: ="Charting: " & Sheet1!$B$1

Getting x values
The next task is to get a list if x values we can use for the x-axes of the chart. A little known fact, is that when a defined name is used to name a formula this formula will be an array formula by default. We're going to put that to use.

First we need a set of incrementing numbers. We'll use the ROW worksheet function for that. When we define this name local to worksheet Sheet1: Name: Sheet1!x RefersTo: =ROW(1:20) and we enter an array formula into cells A1:A20 (select A1:A20 in Sheet1 and type =x, then hit control-shift-enter) we get this result:

But we want the number of x-values to be dependent on a number entered into a cell. We'll use the OFFSET worksheet function for this purpose: =ROW(OFFSET(Sheet1!$A$1,0,0,20,1)) If we replace the previous formula in "Sheet1!x" with the one above, the result will remain the same as shown above. All it takes now is replace the fixed 20 with a cell reference: =ROW(OFFSET(Sheet1!$A$1,0,0,Sheet1!$B$5,1))

Now we have the numbers 1 to 20 (or up to whatever number we enter into cell B5 on sheet1). But we need more flexibility, we want to be able to set a minimum and a maximum value for x and use the 1-20 range to space out these limits. Let's define these named ranges: Name xStart Refers To =Sheet1! $B$3 =Sheet1! $B$4 =Sheet1! $B$5 =xEndxStart

xEnd xNumberOfPoi nts xRange

To get a series of "xNumberOfPoints" from xStart to xEnd, the following formula applies: xPoint=xStart+xRange/(xNumberOfPoints-1)*Counter(1 to xNumberOfPoints-1) So applying the approach depicted above: =xStart+xRange/(xNumberOfPoints-1)*(ROW(OFFSET(Sheet1! $A$1,0,0,xNumberOfPoints,1))-1) We'll name this new formula (surprisingly): Sheet1!x

Getting y values
Now that we have gotten a dynamic set of x values it is time to derive results. Again we'll define a named range:

Name

Refers To

Formul =Sheet1! a $B$1 What we need is a mechanism to evaluate the formula in cell B1 using the x values we have available. For this we'll use the fact that Excel accepts ancient xl4 macro functions inside defined names. The function needed is the EVALUATE function, which we use in the name y, local to worksheet Sheet1: Name Refers To

Sheet1 =EVALUATE(Formu !y la) Strange enough, this version of y only seems to work for functions that do not use built-in Excel functions like SIN or COS, using those in the function will cause Excel to compute all constant values, regardless of the x's! Stephen Bullen has created an almost identical version of this workbook a long time ago, using Excel 5. Look for a download calledChtFrmla.zip. He used a trick to make these functions work by adding "0*x" to the set of y values: Name Refers To

Sheet1 =EVALUATE(Formula&"+0 !y *x") Suddenly, including Excel functions has become possible!

Using Controls On Worksheets


Where to find the controls

Excel 2007 and up


In Excel 2007 and later versions, the form controls and control toolbox controls are slightly hidden. First of all, you need to show the "Developer" tab of the ribbon. Here is how that's done:

Click the Office button and select "Excel options..." (for Excel 2010 and up: Click File, Options and then locate this option on the "Customize ribbon" tab). Click the "Popular" tab and check the box next to "Show Developer tab in the ribbon":

Fig 1: Showing the Developer tab on the ribbon (Excel 2010 and up).

After you've checked the box and clicked OK, you will find a new tab called "Developer" on your ribbon. This tab houses a group called "Controls", which in turn contains a button "Insert". The dropdown list shows all available controls:

Fig. 2: The controls on the Developer tab.

Excel 97-2003
In older Excel versions the controls are housed on two toolbars; the "Forms" toolbar and the "Control toolbox" toolbar. You can show both toolbars using the menu "View", "Toolbars":

Fig. 3: Access to the controls toolbars in Excel 97-2003.

After turning on these two toolbars they are shown:

Fig. 4: The control toolbars in Excel 97-2003.

Two groups of controls; the differences

By now it is apparent that there are two distinct series of controls: Those from the forms group and those from the Control toolbox (named ActiveX controls in Excel 2007 and up).

Pro's and con's


The table below lists some advantages and disadvantages of both control sets: Control type Form controls

ActiveX controls

Advantages

Simple to use Can be used on chart sheets Assigning control to a macro is simple Little known problems

Lots of optio Lots of even Lots of form Lists return than the ind

Disadvantag es

Lists return the index number rather than the selected value

Cumbersom multiple con Sometimes corruptions

Which should you use


By now you'll be wondering which set you should use. Generally speaking, I recommend using the controls from the forms toolbar. If you have specific needs regarding formatting which cannot be achieved using the forms controls (or if you want to program events in VBA), then you'll have to switch to the ActiveX controls (control toolbox controls).

Inserting controls
Inserting a control on your sheet is very simple: Just click the control you need (See fig. 2 and 4 on the previous page) and drag a rectangle on the sheet at the position where you want the control to appear. You can also just click on the sheet and have Excel decide what dimensions to use for the control. If you hold down the alt key when you click on the worksheet, then the control will be aligned to the cell grid. You can also hold the alt key when you are dragging the control or resizing the

control to have it snap to the grid. This is a quick way to ensure your controls are nicely aligned and of equal size. Double click a control on the toolbar or on the Insert controls dropdown if you want to draw multiple copies of that control. Click that control again (or any other control) to get out of that mode.

Overview of the available controls


The table below shows which controls there are and describes each one shortly. Pic Control name . Label Frame Control use and remarks Add a label next to other controls.

Use this control to group other controls. OptionBu work together.

Button(CommandButt Start a macro on) CheckBox OptionButton ListBox ComboBox ScrollBar Spinner

Set an option, Select multiple options from a list o Select one option from a (short) list.

Select an option from a list. Multiple options are vi

Select an option from a list, only the selected optio Quickly change numeric values. Change values step-by-step easily.

TextBox ToggleButton

Enter a text. Toggle status. This control is not recommended, I checkbox or a set of two OptionButtons.

Detailed description of the controls (1)


Label
The label control is the simplest control available, all it can be used for is to display descriptive text. Use this control if you want to add some explanatory text to another control. TIP: You can make sure the label text is derived from a worksheet cell. To do so, select the label and then click in the formula bar and enter a reference to the cell. See fig. 5.

Fig 5: The text on a label drawn from a worksheet cell

Frame
You can use a frame to visually group controls with a shared purpose. Apart from that, the frame control has a specific function for option button controls (see the appropriate section about them). You must start with drawing the frame control before adding the controls you want placed "inside" the frame. To make this a painless process, start out by drawing a relatively large frame (you can make the frame smaller later on). After that, draw the controls inside the frame:

Fig 6: Frames with OptionButtons within.

Button (CommandButton)
Buttons or CommandButtons are used to start VBA code (macro's). If you draw a Button from the Forms toolbar on a sheet, Excel will prompt you for a macro to run when the button is clicked (fig 7). If you have not written a macro yet, then you can type the macro's name and click the "New" button to have the (empty) subroutine created for you:

Fig 7: Excel asks you what macro to run when the button is clicked.

If you used the CommandButton from the Control toolbox, you need to double-click the button (in design mode) to access it's

VBA click event. Code for control toolbox (ActiveX) controls is typically written in the code module behind the sheet they are placed on. TIP: If you want to change the properties of a control from the control toolbox (an ActiveX control), then you must put your sheet into "Design mode". In Excel 2003 you can click the first button on the control toolbox toolbar. In Excel 2007 and up you can find this button on the "Developer" tab, within the "Controls" group. When you want to start using the controls, click the same button to get out of design mode.

Detailed description of the controls (2)


CheckBox
Typically, a checkbox control is used to enable the user to turn something on or off, or to answer a yes/no question. The checkbox always stands on its own, allowing multiple options to be selected (checked) at the same time.

OptionButton
The option button is very similar to the check box, but only allows mutually exclusive choices to be made; in a set of option buttons, only one option can be "checked". If you take no specific action then all option buttons on one sheet will be treated as one single group. It is possible to have multiple groups on a sheet. The method to achieve this differs between the two sets of option buttons. The method to tie an option button to a cell differs between the two types too. Forms option button To group option buttons from the forms toolbar, first draw frames on your sheet. Then draw the option buttons INSIDE the frame:

Fig 8 : Two frames with option buttons.

Option buttons from the forms toolbar share their linked cell. The value returned to the cell is the index number of the selected option. Note that the index will match the order in which you created the option buttons. To select a control from the forms toolbar (for example to be able to move the control), either right-click the control or control+click it. To select multiple controls to change their properties in one go, hold control while clicking them. Group controls you want to keep together, for example those within a frame, by control+clicking them in turn and then rightclicking on one of their edges and selecting "Grouping", "Group". Control toolbox option button (ActiveX) The option button from the Control toolbox toolbar (ActiveX) has a special property to set up which work together, called the Groupname property:

Fig 9: Groupname property of the ActiveX OptionButton control.

If you do not change this property, all option buttons on a sheet work together as a single group. ActiveX option buttons all have their own linked cell, which will receive the checked state of their parents as a True/False value. TIP: You can get at the properties window of the controls by right-clicking a control and selecting "Properties". You can also click the appropriate button on the Control Toolbox toolbar. In Excel 2007 and up, you'll find that button on the Developer tab, within the Controls group.

Detailed description of the controls (3)


ListBox
If you want to enable your user to select an option from a list you can use a list box. Of course you could also use a set of option buttons for this goal, but making a set of option buttons dynamic (for example if you want to be able to expand the number of choices) is cumbersome. If you have a limited set of available choices (rule of thumb: no more than 5), use option buttons. If there are more, use a list box or a combo box control.

You can either have the control pick up the list from a range of cells, or add the choices to the list box control using VBA. This is done by entering the corresponding information into the ListFillRange or Input range property. If your list of choices resides on a different worksheet from the one your list box is placed on, you must define a range name for the list. Do so by selecting the list and hitting control+F3. In Excel 2007 and up you then need to click the "Add" button. Enter a name for the list and click OK until you're back in Excel. After that, you can enter this new range name in the appropriate property of the control. The second most important property is the LinkedCell (cell link), this cell will receive the result of selecting an item in the list box:

Fig 10, Two important propeties of the ActiveX list box control.

Fig 11: Two important properties of the forms list box.

Note that the list box from the forms toolbar will show the index of the chosen item in the cell, whereas the control from the control toolbox returns the actual value to the cell. For the list box from the forms toolbar, use a formula like this one to get the actual value:
=INDEX(ListForComboAndList,C1)

You can set the list box to "Multi" or "Extended" to enable multiple selections. In that case, the linked cell will show either a zero for the list box from the forms toolbar or #N/A for the control toolbox list box control. You will have to use VBA to read what items have been selected and act accordingly.

ComboBox
A combobox is very useful when there are many values to choose from and when you only want to show the chosen item. With the combobox from the Control toolbox you can dynamically add items to the list -using VBA- when the user types a new item in the box instead of selecting an existing item. The combo box form

the forms toolbar does not have this possibility: the user is limited to the choices available in the list. The two important properties LinkedCell and ListFillRange operate in the exact same way as for the list box control.

Detailed description of the controls (4)


ScrollBar
The most important reason to use a scrollbar is to be able to change a value very quickly. The user can drag the scroll button, click next to the scroll button to change "page" or click the arrows to increase or decrease the value stepwise.

Fig 12: Scrollbar with linked cell.

A vertically placed scroll bar works opposite compared to a spinner control. Clicking the up arrow on a spinner increases the value; clicking the up arrow on a scroll bar decreases the value. In my opinion, the former is more intuitive. If I need this vertical setup, I prefer to use a spinner over a scroll bar. A scroll bar enables you to change the value in two ways. The "Incremental change" is performed by clicking the arrow buttons, the "Page change" is performed by clicking next to the scroll button. See fig. 13:

Fig 13, Two levels of step sizes.

These properties have a different name for the scroll bar of the Control Toolbox toolbar (ActiveX) "SmallChange" and "LargeChange" respectively, see figure 14:

Fig 14, Setting properties of the ActiveX controls scroll bar.

Scroll bars can only work with integers. The range you can use differs between the two families. The forms control ranges from 0 to 30,000. The ActiveX control can go as high as 666,666. If you need steps less than 1, then use a calculation. For example if you need a step size of 0.5, divide the linked cell's value by 2.

Spinner
If you want to be able to quickly change a cell value stepwise, the spinner is the place to be.

Fig 15: Spinner controls.

Setting up spinner controls works identical to the scroll bar control, using the same properties. Of course the spinner does not have a Page change (LargeChange) property.

TextBox
There is only one text box control, member of the ActiveX family of controls, on the Control Toolbox toolbar in Excel 2003 and before. I find this control to have little use, because you can simply use a cell and enter text into the cell directly.

ToggleButton
The last control I discuss here is the toggle button. This is another example of a control that is only available through the ActiveX family of controls. In my opinion, this control is ambiguous. It could be used to either indicate an action, or a state. You could use a control like this to change the page setup of a sheet from portrait to landscape and vice versa. Disadvantage of this control is that the state and action paradigm are conflicting, especially if the two states have a different name (like in the example). Suppose you want to enable toggling between portrait en landscape. You might be tempted to use a toggle button, which has some VBA attached to it to set the option and which updates the caption of the control. What does the caption indicate, the current status, or the status AFTER clicking the toggle button?

Fig 16: Ambiguity when using a toggle button: which one indicates we're in Portrait mode?

Due to this ambiguity a toggle button is only useful to indicate an on or off state for a property which has the same name in both states. For this goal, a checkbox is to be preferred. If there are two mutually exclusive choices, consider using two option buttons.

Interaction between controls and worksheet cells


Each control can be tied to a cell and thus (by using that cell in your formulas) affect your spreadsheet model directly and drive interactivity between your model and the user. For the forms controls, you access these options by right-clicking the control in question and selecting "Format control". Each control offers its own set of options, which are located on the "Control" tab. (see figures 11 en 13). Similarly, you can change the properties of the Control toolbox (ActiveX) controls using their properties window.

Conclusion
Excel is a very flexible instrument to perform analyses and what-if scenarios. You use formulas in cells with one or more input cells to calculate the various situations. To ease working with different values and/or choices, you can put the controls from either the Control toolbox or the Forms toolbar to good use. Proper use of these controls make your models easier to use. The controls also enable you to ease data entry and at the same time improve data quality by minimizing the risk of wrong entries. For "day-to-day" use, I recommend the Forms controls. If there are specific options you need which are not offered by the form controls then you can also implement the Control toolbox (ActiveX) controls.

Introduction
In Working with Tables in Excel 2013, 2010 and 2007 I promised to add a page about working with those tables in VBA too. Well, here you go.

It's a ListObject!
On the VBA side there seems to be nothing new about Tables. They are addressed as ListObjects, a collection that was introduced with Excel 2003. But there are significant changes to this part of the object model and I am only going to touch on the basic parts here.

Creating a table
Converting a range to a table starts with the same code as in Excel 2003:
Sub CreateTable() ActiveSheet.ListObjects.Add(xlSrcRange, Range("$B$1:$D$16"), , xlYes).Name = _ "Table1" 'No go in 2003 ActiveSheet.ListObjects("Table1").TableStyle = "TableStyleLight2" End Sub

But the new stuff is right there already: TableStyles. A collection of objects which are a member of the Workbook object. This gives rise to some oddities. You can change the formatting of a tableStyle, e.g. like this:
Sub ChangeTableStyles() 'No Go in Excel 2003 ActiveWorkbook.TableStyles(2).TableStyleElements(xlWholeTable) _ .Borders(xlEdgeBottom).LineStyle = xlDash End Sub

This changes the linestyle of the bottom of your table. But hold your horses! If you have any other workbook open, all tables with the same tablestyle appear in your changed style! But if you save your file, close Excel and open Excel again with the file, the changes are gone. This is because you've just changed a built-in tablestyle. If you ask me, I find it strange that the Workbook is a tablestyles' parent, whereas built-in table styles behave as if being bound to the Application object. If you want full control over your table style, you'd better duplicate a built-in style and modify and apply that style to your table.

Listing the tables


Let's start with finding all tables on the active worksheet:
Sub FindAllTablesOnSheet() Dim oSh As Worksheet Dim oLo As ListObject Set oSh = ActiveSheet For Each oLo In oSh.ListObjects Application.Goto oLo.Range MsgBox "Table found: " & oLo.Name & ", " & oLo.Range.Address Next End Sub

This snippet of code works exactly the same in Excel 2003, so nothing new there (well, that is, in 2003 those tables ARE called Lists).

Selecting parts of tables


You might need to work with specific parts of a table. Here is a couple of examples on how to achieve that. The code comments show you where Excel 2003 differs from 2013, 2010 and 2007.
Sub SelectingPartOfTable() Dim oSh As Worksheet Set oSh = ActiveSheet '1: with the listobject With oSh.ListObjects("Table1") MsgBox .Name 'Select entire table .Range.Select 'Select just the data of the entire table .DataBodyRange.Select 'Select third column .ListColumns(3).Range.Select 'Select only data of first column 'No go in 2003 .ListColumns(1).DataBodyRange.Select 'Select just row 4 (header row doesn't count!) .ListRows(4).Range.Select End With 'No go in 2003 '2: with the range object 'select an entire column (data only) oSh.Range("Table1[Column2]").Select 'select an entire column (data plus header) oSh.Range("Table1[[#All],[Column1]]").Select 'select entire data section of table oSh.Range("Table1").Select 'select entire table oSh.Range("Table1[#All]").Select 'Select one row in table oSh.Range("A5:F5").Select End Sub

As you may have spotted, Excel 2013, 2010 and 2007 handle tables like they are range names. Well, that is exactly what is going on. After inserting a table, a range name is defined automatically. These range names are special though. Excel controls them entirely. You cannot delete them and they get renamed automatically when you change a table's name. Remove a table (convert back to range) and the defined name is removed as well.

Inserting rows and columns


Another part in which lists already had most of the functionality. Just a few new things have been added, like the "AlwaysInsert" argument to the ListRows.Add method:
Sub TableInsertingExamples() 'insert at specific position Selection.ListObject.ListColumns.Add Position:=4 'insert right Selection.ListObject.ListColumns.Add 'insert above Selection.ListObject.ListRows.Add (11) 'NoGo in 2003 'insert below Selection.ListObject.ListRows.Add AlwaysInsert:=True End Sub

If you need to do something with a newly inserted row, you can set an object variable to the new row:
Dim oNewRow As ListRow Set oNewRow = Selection.ListObject.ListRows.Add(AlwaysInsert:=True)

If you then want to write something in the first cell of the new row you can use:
oNewRow .Range.Cells(1,1).Value="Value For New cell"

Adding a comment to a table


This is something Excel 2003 cannot do and is related to the fact that a table is a range name. Adding a comment to a table through the UI is a challenge, because you have to go to the Name Manager to do that. In VBA the syntax is:
Sub AddComment2Table() Dim oSh As Worksheet Set oSh = ActiveSheet 'NoGo in 2003 'add a comment to the table (shows as a comment to 'the rangename that a table is associated with automatically) 'Note that such a range name cannot be deleted!! 'The range name is removed as soon as the table is converted to a range oSh.ListObjects("Table1").Comment = "This is a table's comment" End Sub

Convert a table back to a normal range


That is simple and uses the identical syntax as 2003:
Sub RemoveTableStyle() Dim oSh As Worksheet

Set oSh = ActiveSheet 'remove table or list style oSh.ListObjects("Table1").Unlist End Sub

Special stuff: Sorting and filtering


With Excel 2013, 2010 and 2007 we get a whole new set of filtering and sorting options. I'm only showing a tiny bit here, a Sort on cell color (orangish) and a filter on the font color. The code below doesn't work in Excel 2003. A List in 2003 only has the default sort and autofilter possibilities we have known since Excel 5 and which had hardly been expanded at all in the past 12 years or so.
Sub SortingAndFiltering() 'NoGo in 2003 With ActiveWorkbook.Worksheets("Sheet1").ListObjects("Table1") .Sort.SortFields.Clear .Sort.SortFields.Add( _ Range("Table1[[#All],[Column2]]"), xlSortOnCellColor, xlAscending, , _ xlSortNormal).SortOnValue.Color = RGB(255, 235, 156) With .Sort .Header = xlYes .MatchCase = False .Orientation = xlTopToBottom .SortMethod = xlPinYin .Apply End With End With 'Only old autofilter stuff works in 2003 ActiveSheet.ListObjects("Table1").Range.AutoFilter Field:=2, _ Criteria1:=RGB(156, 0, 6), Operator:=xlFilterFontColor End Sub

Accessing the formatting of a cell inside a table


You may wonder why this subject is there, why not simply ask for the cell.Interior.ThemeColor if you need the ThemeColor of a cell in a table? Well, because the cell formatting is completely prescribed by the settings of your table and the table style that has been selected. So in order to get at a formatting element of a cell in your table you need to:

Find out where in your table the cell is located (on header row, on first column, in the bulk of the table Determine the table settings: does it have row striping turned on, does it have a specially formatted first column, ...

Based on these pieces of information, one can extract the appropriate TableStyleElement from the table style and read its properties.

The function shown here returns the TableStyleElement belonging to a cell oCell inside a table object called oLo:
Function GetStyleElementFromTableCell(oCell As Range, oLo As ListObject) As TableStyleElement '------------------------------------------------------------------------' Procedure : GetStyleElementFromTableCell ' Company : JKP Application Development Services (c) ' Author : Jan Karel Pieterse ' Created : 2-6-2009 ' Purpose : Function to return the proper style element from a cell inside a table '------------------------------------------------------------------------Dim lRow As Long Dim lCol As Long 'Determine on what row we are inside the table lRow = oCell.Row - oLo.DataBodyRange.Cells(1, 1).Row lCol = oCell.Column - oLo.DataBodyRange.Cells(1, 1).Column With oLo If lRow < 0 And .ShowHeaders Then 'on first row and has header Set GetStyleElementFromTableCell = oLo.TableStyle.TableStyleElements(xlHeaderRow) ElseIf .ShowTableStyleFirstColumn And lCol = 0 Then 'On first column and has first column style Set GetStyleElementFromTableCell = oLo.TableStyle.TableStyleElements(xlFirstColumn) ElseIf .ShowTableStyleLastColumn And lCol = oLo.Range.Columns.Count 1 Then 'On last column and has last col style Set GetStyleElementFromTableCell = oLo.TableStyle.TableStyleElements(xlLastColumn) ElseIf lRow = .DataBodyRange.Rows.Count And .ShowTotals Then 'On last row and has total row Set GetStyleElementFromTableCell = oLo.TableStyle.TableStyleElements(xlTotalRow) Else If .ShowTableStyleColumnStripes And Not .ShowTableStyleRowStripes Then 'in table, has column stripes If lCol Mod 2 = 0 Then Set GetStyleElementFromTableCell = oLo.TableStyle.TableStyleElements(xlColumnStripe1) Else Set GetStyleElementFromTableCell = oLo.TableStyle.TableStyleElements(xlWholeTable) End If ElseIf .ShowTableStyleRowStripes And Not .ShowTableStyleColumnStripes Then 'in table, has column stripes

If lRow Mod 2 = 0 Then Set GetStyleElementFromTableCell = oLo.TableStyle.TableStyleElements(xlRowStripe1) Else Set GetStyleElementFromTableCell = oLo.TableStyle.TableStyleElements(xlWholeTable) End If ElseIf .ShowTableStyleColumnStripes And .ShowTableStyleRowStripes Then If lRow Mod 2 = 0 And lCol Mod 2 = 0 Then Set GetStyleElementFromTableCell = oLo.TableStyle.TableStyleElements(xlRowStripe1) ElseIf lRow Mod 2 <> 0 And lCol Mod 2 = 0 Then Set GetStyleElementFromTableCell = oLo.TableStyle.TableStyleElements(xlColumnStripe1) ElseIf lRow Mod 2 = 0 And lCol Mod 2 <> 0 Then Set GetStyleElementFromTableCell = oLo.TableStyle.TableStyleElements(xlRowStripe1) Else Set GetStyleElementFromTableCell = oLo.TableStyle.TableStyleElements(xlWholeTable) End If End If End If End With End Function

You could use this function like this:


Sub test() Dim oLo As ListObject Dim oTSt As TableStyleElement Set oLo = ActiveSheet.ListObjects(1) Set oTSt = GetStyleElementFromTableCell(ActiveCell, oLo) With ActiveCell.Offset(, 8) .Interior.ThemeColor = oTSt.Interior.ThemeColor .Interior.TintAndShade = oTSt.Interior.TintAndShade End With End Sub

Note that the function shown above does not take into account that you can set the width of the stripes, both vertically and horizontally.

Wrap Up
Of course there is more to learn and know about tables and lists. A good way to come acquainted with the VBA behind them is by recording macro's while fooling around with them. Luckily Microsoft did include the table object if it comes to recording your actions, unlike the omission on the charting side...

Custom Find Deze pagina in het Nederlands

Finding Cells Matching A Specific Property Using The CallByName Function


Introduction
I thought it would be nice to have a generic VBA function to which we could pass a range object, a string indicating a property of the object and the property's value, which would then return all cells matching that criteria.

CallByName
I decided it was time to explore the CallByName function, introduced with Office 2000. According to Excel XP VBA Help: CallByName Function Executes a method of an object, or sets or returns a property of an object. Syntax CallByName(object, procname, calltype,[args()]) The CallByName function syntax has these named arguments:
Part object Description Required; Variant (Object). The name of the object on which the function will be executed. Required; Variant (String). A string expression containing the name of a property or method of the object.

procna me

calltype Required; Constant. A constant of type vbCallType representing the type of procedure being called. Can be vbGet (to return a property), vbLet (to change a property), vbMethod (to execute a method) or vbSet (to set an Object)

args()

Optional: Variant (Array).

Suppose we'd want to find out the colorindex of a cell's interior:


Sub test() MsgBox CallByName(ActiveCell.Interior, "Colorindex", VbGet) End Sub

Since I would like to make this method a bit more general, I would like to just pass the cell object and the entire "procname" in a string:
Sub test() MsgBox CallByName(ActiveCell, "Interior.Colorindex", VbGet) End Sub

Unfortunately, this does not work, "procname" only accepts a single entity (Property, Method or Object). So it is necessary to split up the "procname" string into it's individual elements. Something like this (note: Excel 97 doesn't have the Split function, nor the CallByName function):
Dim lProps As Long Dim vProps As Variant vProps = Split(sProperties, ".") lProps = UBound(vProps)

So to get at the colorindex property of the Interior object of the Cell object, we need to loop through the variant vProps:
For lCount = 0 To lProps - 1 Set oTemp = CallByName(oTemp, vProps(lCount), VbGet) Next

We stop the loop at the one-but-last element of vProps, because all of the elements except the last one will be objects and the last one will be the property we're interested in. Then we get the property of the last object the loop has given us: CallByName(oTemp, vProps(lProps), VbGet) The complete function is shown below:
Function FindCells(ByRef oRange As Range, ByVal sProperties As Strin g, _

ByVal vValue As Variant) As Range Dim oResultRange As Range Dim oArea As Range Dim oCell As Range Dim bDoneOne As Boolean Dim oTemp As Object Dim lCount As Long Dim lProps As Long Dim vProps As Variant vProps = Split(sProperties, ".") lProps = UBound(vProps) For Each oArea In oRange.Areas For Each oCell In oArea.Cells Set oTemp = oCell For lCount = 0 To lProps - 1 Set oTemp = CallByName(oTemp, vProps(lCount), VbGet) Next If CallByName(oTemp, vProps(lProps), VbGet) = vValue Then If bDoneOne Then Set oResultRange = Union(oResultRange, oCell) Else Set oResultRange = oCell bDoneOne = True End If End If Next Next If Not oResultRange Is Nothing Then Set FindCells = oResultRange End If End Function

A small example of its use, selecting all cells with a white fill:
Sub UseFindCellsExample() FindCells(ActiveSheet.UsedRange, "Interior.ColorIndex", 0).Select End Sub

Вам также может понравиться