Monday, November 28, 2011

Advanced Excel: Macro Examples

Creating Excel spreadsheet macros is a great way to save time and reduce the possibility of human error by automating repetitive processes. Other reasons for learning how to write VBA macros include: standardization, improve efficiency, expand capabilities, and streamline tasks. Macros in Excel are created through two primary methods: the macro recorder or by writing custom code with the macro editor (or even with notepad). Recording is a great way to figure out syntax or a specific, simple task if you are stuck but writing custom code is far superior, especially if you are dealing with multiple Excel files. Here are a few basic, easy lines of code which are helpful to learn when beginning to create macros. Most of these deal with layout or formatting of your spreadsheet. I typically would add these types of commands to the end of my macro after all the data is where I would like it.


To insert a row above an active cell use this code:

ActiveCell.EntireRow.Insert

Conversely, to insert a  row below the active cell:


ActiveCell.Offset(1).EntireRow.Insert

To insert a new, blank column to the left of the active, selected cell, use this:


ActiveCell.EntireColumn.Insert

Or, to insert a column to the right of the active cell, change to this:


ActiveCell.EntireColumn.Offset(0, 1).Insert



To delete a column, specify the column number (A being 1, B = 2, and so on):


ActiveWorkbook.ActiveSheet.Columns(16).Delete


To add a diagonal line through a range of cells with a macro use the following code:


Range(insert desired range , ie A2:B2).Select
    Selection.Borders(xlDiagonalDown).LineStyle = xlNone
    With Selection.Borders(xlDiagonalUp)
        .LineStyle = xlContinuous
        .ColorIndex = 1
        .TintAndShade = 0
        .Weight = xlThin
    End With

To change the background color to white, select a range of cells then type this:



With Selection.Interior
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .ThemeColor = xlThemeColorDark1
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With


To create a thick border on the right of a cell:


Selection.Borders(xlEdgeRight).Weight = xlThick


Or, make the bottom border thick:


Selection.Borders(xlEdgeBottom).Weight = xlThick


To Autofit a columns width, specify a range:


Range(AA:CC).EntireColumn.Autofit
Read more about creating Excel spreadsheetmacros.

Monday, November 14, 2011

How to use the SUMIF formula in Excel

SUMIF is a useful formula to know how to use when creating Microsoft Excel spreadsheet templates. An example I can give is from the world of engineering. Say you have to create a part list or a bill of material (BOM for an assembly, such as a snow blower. The snow blower has multiple parts with have standard parts, such as washers, bolts, nuts, etc,, attached to it. At the bottom of my BOM I want to sum all of the parts for my top level assembly but I don’t want to include the number of standard nuts and bolts. In this case I use the SUMIF formula along with some nifty formatting.

 
 
To count the number of parts in a specified column use the =SUMIF() formula. In my case, =SUMIF(K5:K17,">0").
If a number exists in a column which is greater than zero then sum the given range in the column.

One thing that I did was to change the standard part counts, which used to be entered as (1), (2), (3), etc. (entered '(1)). I have since changed this to a new format: -1, -2, -3... yet the entries still look like (1), (2), (3).  This way the SUMIF formula can count the numbers since they are not being recorded as text.  With the numbers being negative it can also make it so the formulas can selectively count them in the different parts of the spreadsheet.  So, when entering parts like weld nuts, nut plates, pin, collars, etc. enter the count as a negative (-) number.  This can either be done as -1 or (1), both will mean the same. I also put in a custom number format so you  no longer have  to type "-1", "-2", etc.  Just enter 1, 2, 3, etc. and the "-" will be placed in front automatically. Little improvements like this go a long way in improving the time it takes to compile one of these massive spreadsheets.

Let me know if you have any questions or concerns and if this format is more or less helpful and an improvement in function and readability.

Monday, November 7, 2011

Why doesn't center alignment macro work?

Troubleshooting Excel macros
I was recently working on an Excel spreadsheet macro to automatically center the text with a cell on the cells within a sheet. This is a VBScript macro executed from a CAD system and exports desired data to an Excel file. I used the following code:

With Excel.Range("A"&"1", "F"&RwNum)

.Font.Name = "Arial"

.Font.Size = 9

.HorizontalAlignment = xlCenter

.VerticalAlignment = xlCenter

.ColumnWidth = 25

.RowHeight = 20

.Borders.LineStyle = xlContinuous

.Borders.Weight = xlThick

.Borders.ColorIndex = 1

.WrapText = True

.EntireColumn.Autofit


End With


Well, the Horizontal and Vertical alignment was not working at all. I tried numerous different methods, spellings, etc. Nothing seemed to work. Then I discovered I was missing a line of code. Simply add this statement before the With loop:

Const xlCenter = -4108

Because we're accessing a spreadsheet from outside of Excel the xlCenter constant is not declared which makes VBA treat it as 0. So in our code we need to set a value for xlCenter, hence the code line of: Const xlCenter = -4108. Here are some other values you may need to set if you are formatting or sorting your Excel sheet.

Const xlCenter = -4108
'Const xlAscending = 1
'Const xlYes = 1
'Const xlSortOnValues = 0
'Const xlSortNormal = 0
'Const xlTopToBottom = 1
'Const xlPinYin = 1

To figure out the value number go into excel VBA editor and press crtl+g then type ?xlAscending and it will list the current value.

To sort a list using VBScript as opposed to VBA here is an example code you might need:

'sort parts in numerical order then sort fasteners
Excel.Range("A:G").Select

Excel.Selection.Sort Excel.Range("G1"),1,Excel.Range("A1"),,1,Excel.Range("B1"),1,1,1,False