cellmatrix.net

Simple Goal Seek Procedure

Unfortunately Excel's goal seeking feature forces you to hand-enter a value into the "To value" field of the input box. You can't directly tie this input to a cell like you can with the "Set cell" and "By changing cell" inputs (see the screenshot below).

image

This can make things difficult especially if you're trying to seek very large values or values that that are carried out to many decimal points.

The following procedure allows you to get around this limitation. First, enter the cell addresses for the variables called Rng1, Rng2, and Rng3. Note that a formula must appear in Rng1 and a value must be entered into Rng3. Next, run the procedure.

Sub GoalSeek()

    
Dim Rng1 As Range
    Dim Rng2
As Range
    Dim Rng3
As Range

    On Error GoTo errHandler
:

    
'Set the value in this cell
    Set Rng1 = ActiveSheet.Range("C4")

    '
Equal to the value in this cell
    
'Note:  This cell must contain a formula
    Set Rng2 = ActiveSheet.Range("C7")

    '
By changing the value in this cell
    Set Rng3
= ActiveSheet.Range("C2")

    If
Rng1.HasFormula = True Then
        
If IsNumeric(Rng3) = True Then
            Rng1
.GoalSeek Goal:=Rng2, ChangingCell:=Rng3
        End
If
    
End If

    Exit
Sub

errHandler
:
    
MsgBox "Procedure failed - please check inputs."

End Sub

Size and Export Embedded Charts as .GIF Images

To add images of embedded charts to this weblog, I use the VBA procedure below. To run the procedure, first make sure the specifications are correct. You can make changes to the chart height, width, file name, and file path. When all of the inputs are correct, click on (activate) the embedded chart and run the macro.

Sub ExportChart()

    
Dim Cht As ChartObject
    Dim Path
As String
    Dim FileName
As String
    
    Set Cht
= ActiveChart.Parent

    Cht
.Height = 210
    Cht
.Width = 336
    FileName
= "2008032301.gif"
    
Path = "C:\Program Files\"
    
    
ActiveChart.Export Path & FileName

End Sub

Please note that the height and width are not really needed. I've added this code only because I like to make sure all of the charts are exactly the same size.

Lookups and VBA Loops for Reporting

Many companies produce reports at a top-level, department, division, and/or cost center level. When Excel is used to build these reports, the normal practice seems to be to create a new sheet for each department, division, and/or cost center. Each sheet contains the data and calculations for that area. A single top-level reporting sheet is then created to which each department, division, and/or cost center sheet links to. When it's all over and done the workbook can become very large, prone to error, and difficult to audit.

An easier and more accurate approach is to use the combination of lookup formulas and a VBA loop to build the report. In this example, only four sheets in the Excel file are illustrated (it could be only one if designed that way). The first sheet, called "dBase", contains the raw data for each department, division, and/or cost center. The second sheet, called "Calcs", contains a single set of calculations needed to build the final report. The third sheet, called "Load", contains a summary of the data from the Calcs sheet needed for the final report. The final sheet, called "Report", is the final report.

The example begins with a screenshot of the sheet called "dBase" (for database). The "dBase" sheet contains ten departments. The Commerical / Contract and Government volumes for each department is provided for the years 2007 and 2008. The final report requires that you show the components of payer mix variance for each department.

image

The next screenshot shows the sheet called "Calcs". The blue cell (C2) contains the name of the department. The yellow cells contain lookup formulas that reference the "dbase" sheet.

image

For example, the lookup formula in cell E8 is:

=VLOOKUP($C$2,dBase!$A$3:$E$12,2,FALSE)

The lookup formula in cell F8 is:

=VLOOKUP($C$2,dBase!$A$3:$E$12,4,FALSE)

The next screenshot shows the sheet called "Load". The purpose of this sheet is to reference all of the values that need to appear in the final report into one row of data.

image

The data that appears in the "Load" sheet is referenced to the green cells in the "Calcs" sheet.

image

Finally, a VBA procedure is run to create the report. A loop is created that, when combined with the lookup formulas, does the following:

  • The VBA procedure loads the name of the department into cell C2 of the "calcs" sheet.
  • The lookup formulas in the calcs sheet reference the data from the "dBase" sheet for that particular department.
  • The payer mix calculations are performed.
  • The payer mix data is referenced from the "calcs" sheet into row of data in the "Load" sheet.
  • The data from the "Load" sheet is copied as values into the final report.

In this example, the procedure described above is performed ten times - once for each department as referenced in the range B8:B17 of the "Report" sheet. The VBA code that performs the work is below:

Sub BuildReport()
    
Application.ScreenUpdating = False
    Dim Rng1
As Range
    Dim Rng2
As Range
    Dim Rng3
As Range
    Dim Rng4
As Range
    Set Rng2
= Sheets("Calc").Range("C2")
    
Set Rng3 = Sheets("Load").Range("B3:G3")
    
Set Rng4 = Sheets("Rpt").Range("C8:H8")
    For
Each Rng1 In Sheets("Rpt").Range("B8:B17")
        
Rng2.Value = Rng1.Value
        Rng3
.Copy
        Rng4
.PasteSpecial xlPasteValues
        Set Rng4
= Rng4.Offset(1, 0)
    
Next Rng1
    Sheets
("Rpt").Range("A1").Select
End Sub

After the macro has been run, the final report looks like this:

image

The advantages of using lookup formulas and VBA loops to build the report are these:

  • Only one set of calculations (the "Calcs" sheet) needs to be audited for accuracy. This is especially advantageous as the number of departments, division, etc. needed on the final report grows.
  • The audit risk concerning the workbook is reduced due to less sheets and data ranges needing to be proofed.
  • The physical size of the workbook is reduced which make it easier to maintain and transfer to others via email, web, etc.
  • The VBA procedure runs fast and the report is produced almost instantaneously.

Potential disadvantages of using lookup formulas and VBA loops to build the report are these:

  • If you need to pass the workbook on to someone that has no experience with VBA, the issue of who can maintain the workbook may come up.
  • If your manager is clueless when it comes to lookups or VBA, he or she may prefer the "many sheets and calculations" approach so they can understand it (runs hand-in-hand with the first bullet).

Fill a Blank Range with Zeros

The need to fill a blank range with zeros often occurs when dealing with data that is downloaded from a mainframe. Recently I've seen several examples that utilize a loop structure to fill a blank range with zeros. Rather than using loops, below is an example that utilizes the SpecialCells method to fill a range.

Sub FillBlanksWithZeros()
    
Dim Rng As Range
    On Error GoTo ErrHandler
    Set Rng
= Range("A1:B10")
    
Rng.SpecialCells(xlCellTypeBlanks) = 0
    
Exit Sub

ErrHandler
:
    
MsgBox "Error # " & Err.Number & " - " & Err.Description
End Sub

The SpecialCells method is much faster than using a loop structure.


Returning Non-Integer Values from Scrollbars

A recent post to the Microsoft Excel Charting Newsgroup asked "how can I return a non-integer value from a scrollbar? A VBA approach would be to divide the scrollbar output by 10, 100, 1000, etc. Assuming the scrollbar is named "SB1", the example below returns values between 0.1 and -0.1:

Private Sub SB1_Change()
  
Range("A1").Value = SB1.Value / 1000
  ScrollBar1
.Max = 100
  ScrollBar1
.Min = -100
End Sub

Private Sub SB1_Scroll
()
  
Range("A1").Value = SB1.Value / 1000
  ScrollBar1
.Max = 100
  ScrollBar1
.Min = -100
End Sub

Load Array From Worksheet Range

This simple procedure loads the values in the range A1:A5 into an array. The Debug.Print statement prints the contents of the array in the Immedicate Window of Visual Basic Editor.

Sub LoadArrayFromRange()

    
Dim arrRange()
    
Dim Rng As Range

    x
= 0

    
For Each Rng In Range("A1:A5")
        
ReDim Preserve arrRange(x)
        
arrRange(x) = Rng.Value
        x
= x + 1
    Next Rng

    
For Each Item In arrRange
        Debug
.Print Item
    Next

End Sub

I'm not sure where I found this so unfortunately I can't credit the original author.


Reverse Items in an Array

Last weekend I spent several hours searching Excel's Help and the Internet trying to come up with a procedure to reverse the items in a one-dimensional array. I was using an array as the source for a listbox load and the loop below to load the items into the listbox:

For Each Item In Array1
     frmTrace
.ListBox1.AddItem Item
Next Item

Unfortunately this routine loads the data from low to high instead of high to low. After spinning my wheels, I posted my problem to the Microsoft Programming Newsgroup and it was solved within hours. I received three responses and all three worked. Below is the simplest correction:

For Each Item In Array1
     frmTrace
.ListBox1.AddItem Item, 0
Next Item

Thanks to those in the Programming Newsgroup who helped me with this.


Trigger Macro on Range and Sheet Changes

I always seem to spend ten minutes trying to find these snippets of code on the Internet when I need them. For reference . . .

To trigger a macro on a change in range, load the procedure below into a sheet module. It will fire when a change is made to the range A1:A5.

Private Sub Worksheet_Change(ByVal Target As Excel.Range)
    If
Not Intersect(Target, Range("A1:A5")) Is Nothing Then
        Your Code Here
    End
If
End Sub

To trigger a macro on a change in the sheet, load the procedure below into a sheet module. It will fire when a change is made to any cell on the sheet:

Private Sub Worksheet_Change(ByVal Target As Range)
    
Your Code Here                
End Sub

About

Formulas, Charts, and Models Created with Microsoft Excel.

Read more...

Statistics

  • Total Entries - 83
  • Current Viewers - 3
  • Days Online - 467

Categories

Entries by Day

July 2008
S M T W T F S
29 30 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 1 2

Excel Web Logs

Syndicate

Validate

My Resources...

Copyright © 2007 - 2008