Results 1 to 5 of 5

Thread: EXCEL: Example: Execute User Code 1 time when sheet data changes.

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    May 2004
    Location
    Carlisle, PA
    Posts
    1,045

    Resolved EXCEL: Example: Execute User Code 1 time when sheet data changes.

    Esteemed Forum Participants and Lurkers:
    ===============================
    EXCEL VBA

    I have an application where I am doing a special trending function on the last 10 data points in a series. My Chart fetches data from a certain fixed area on a sheet, and I have code that is supposed to update this area when new data is added to the end of the list in columns A and B. Once this is achieved, the Chart sheet will always show the new trend line for any new data that gets added.

    The problem was that the "Worksheet_Change" Event fires immediately with any instruction that changes anything on the sheet, which rapidly degenrates into a nasty endless loop. I finally came up with the following solution to execute my update code only one time when data is added to my list. The following is a simplified example just to show the basic procedure. It will count all 'changes' to Column 1.
    Code:
    EXECUTING USER CODE ONE TIME WHEN DATA ON SHEET CHANGES
    Copyright (c) 2005  Arthur Du Rea
    
    * Set a Global Boolean Variable in the User Module
    * Initialize that variable in the Workbook_Open Event
    * Set up the Worksheet_Change Event to prevent False Recursion
    * Implement Code to execute
    
    The "Workbook_Open" Event is a standard method in the "ThisWorkbook" Class Module
    
    To create/open the "ThisWorkbook" Module:
      In the VB Window:  Menu Bar  >  View  >  Object Browser
      In the Libraries Menu Box, select "VBAProject"
      In the "Classes" pane, doubleclick the "ThisWorkbook" item
        This opens the "ThisWorkbook (Code)" window
    
      In the left selection box at the top of the window, select "Workbook"
      In the right selection box at the top of the window, select "Open"
    
    The code template for "Workbook_Open" should appear in the "ThisWorkbook" Module window
    =======================================================================================
    Option Explicit
    'Class Module:  ThisWorkbook(Code)      This is a pre-defined Excel Class Module
    '
    'Global variables used here are actually defined in the USER Module - not here!
    'Public gb_READY as BOOLEAN   <<<< The code for this is in the top of the USER module
    '
    'This is the EVENT that fires when a workbook opens.
    Private Sub Workbook_Open()
        'Initialize the READY flag to allow code execution on Worksheet_Change
        gb_READY = True
    End Sub
    =======================================================================================
    Open the Sheet Module as above ... it is similar to Sheet1(SheetName)
    =======================================================================================
    Option Explicit
    'Module:  Similar to "Sheet1(SheetName)"      This is a pre-defined Excel Module
    '
    Option Explicit
    Private Sub Worksheet_Change(ByVal Target As Range)
        'Do NOT Recurse this routine!
        If gb_READY Then
            'Turn the READY flag OFF
            gb_READY = False
            
            'TEST TEST TEST TEST
            MsgBox Target.Address    'Show what was changed
            'END TEST
            
            'Here is an example of only operating on certain changes
    
            'We only care about changes to the first column
            If Target.Column > 1 Then gb_READY = True: Exit Sub
            
            'Ready to update the code-driven area!!!
            Macro1
        End If
    End Sub
    
    =======================================================================================
    The following is a regular Macro.  You can set the template by recording a Macro
    =======================================================================================
    Option Explicit
    'Module:  Module1 (Code)    'This is a standard User defined Macro Module
    '
    'GENERAL DECLARATIONS AREA:    (MUST precede any Sub or Function declarations)
    'Define the GLOBAL variable - it is available to other modules in the project
    Public gb_READY as BOOLEAN
    
    'Macro to Operate on the data on the sheet
    Sub Macro1()
        'The next line causes a NEW Worksheet_Change Event to be executed BEFORE continuing!
        ActiveSheet.Cells(3,1).Value = ActiveSheet.Cells(3,1).Value + 1
        '    ...
        '  All code that changes the sheet goes here
        '    ...
        'We are done making ALL changes to the Sheet data
        gb_READY = True
    End Sub
    Good Learning and Good Programming!
    Last edited by Webtest; Sep 23rd, 2005 at 12:01 PM.
    Blessings in abundance,
    All the Best,
    & ENJOY!

    Art . . . . Carlisle, PA . . USA

  2. #2
    Fanatic Member VBAhack's Avatar
    Join Date
    Dec 2004
    Location
    Sector 000
    Posts
    617

    Re: EXCEL: Example: Execute User Code 1 time when sheet data changes.

    The following may not apply in your case, but there is a way using the Offset function to have charts update automatically when new data is entered, w/o the use of macros.

    http://j-walk.com/ss/excel/usertips/tip053.htm

    VBAhack

  3. #3

    Thread Starter
    Frenzied Member
    Join Date
    May 2004
    Location
    Carlisle, PA
    Posts
    1,045

    Re: EXCEL: Example: Execute User Code 1 time when sheet data changes.

    Hack ...

    That's a very valuable tip! No it doesn't apply in my case ... but I will definitely put it in my reference Cookbook!

    I have a static area for my chart, but the data has to change based on other data that gets entered on the sheet. I wanted my calculated data block updated with the newly entered data in my series. Sometime, I may need to combine BOTH approaches!

    Thanks again!
    Blessings in abundance,
    All the Best,
    & ENJOY!

    Art . . . . Carlisle, PA . . USA

  4. #4
    Lively Member JustinLabenne's Avatar
    Join Date
    Jul 2005
    Location
    Ohio
    Posts
    64

    Re: EXCEL: Example: Execute User Code 1 time when sheet data changes.

    This is a WorkSheet_Change event that updates an embedded charts data range accordingly:

    VB Code:
    1. Option Explicit
    2.  
    3. Private Sub Worksheet_Change(ByVal Target As Range)
    4.      '   Credit to Aaron Blood as the originator of this code:
    5.      '   [url]http://www.xl-logic.com/pages/charts.html[/url] (DynamicChart3.zip)
    6.     Dim oChrt As ChartObject
    7.     Dim szSeries As String
    8.      
    9.      
    10.     On Error Goto ErrExit
    11.     Application.EnableEvents = False
    12.      
    13.     Set oChrt = ActiveSheet.ChartObjects(1)
    14.      
    15.     If Not oChrt Is Nothing Then
    16.          
    17.         For Each oChrt In ChartObjects
    18.              
    19.              
    20.             szSeries = oChrt.Chart.SeriesCollection(1).Formula
    21.              
    22.             szSeries = Left(szSeries, InStrRev(szSeries, ",") - 1)
    23.              
    24.             szSeries = Right(szSeries, (Len(szSeries) - InStrRev(szSeries, ",")))
    25.              
    26.             oChrt.Chart.SetSourceData Source:=Range(szSeries).CurrentRegion
    27.              
    28.              
    29.         Next oChrt
    30.          
    31.     End If
    32.      
    33.     Set oChrt = Nothing
    34. ErrExit:
    35.     Application.EnableEvents = True
    36. End Sub

    I think the code you are using to tell if a change happened only in column 1 could be simplified more to this: as it makes the change, and avoids your endless loop issue. You could combine the above code plus this one below into one fairly easy, but if you have trouble or this isn't what you needed, post back.

    VB Code:
    1. Option Explicit
    2.  
    3. Private Sub Worksheet_Change(ByVal Target As Range)
    4.     If Target.Column <> 1 Then Exit Sub
    5.    
    6.     On Error GoTo ErrorHandler
    7.     With Application
    8.         .EnableEvents = False
    9.        
    10.         With ActiveSheet
    11.             .Cells(3, 1).Value = .Cells(3, 1).Value + 1
    12.         End With
    13.        
    14. ErrorExit:
    15.         .EnableEvents = True
    16.     End With
    17.     Exit Sub
    18.    
    19. ErrorHandler:
    20.     MsgBox Err.Description
    21.     Resume ErrorExit
    22. End Sub
    Justin Labenne
    www.jlxl.net

  5. #5

    Thread Starter
    Frenzied Member
    Join Date
    May 2004
    Location
    Carlisle, PA
    Posts
    1,045

    Re: EXCEL: Example: Execute User Code 1 time when sheet data changes.

    Thanks Justin ...

    That is some good information to keep in mind and I learned a lot from your post. FYI, and for posterity, the situation changes when you have a separate worksheet for a chart ... "Sheets("chartsheetname").ChartObjects.Count" returns a ZERO (even though there is obviously a chart on the sheet!). You have to switch to "Charts()" rather than "Sheets()".
    Code:
    MsgBox ActiveWorkbook.Charts.Count                   'Shows COUNT of CHART sheets
    MsgBox ActiveWorkbook.Charts(1).ChartObjects.Count   'Shows ZERO!!!
    MsgBox Charts(1).Name                                'Shows my sheet name "Chart1"
    MsgBox Charts("Chart1").SeriesCollection(1).Formula  'Shows "SERIES" formula
    So, a ChartObject only refers to a Chart on a regular WorkSheet. Incidentally, the formula line will give you the SERIES formula for X/Y Scatter Plots, in case you were wondering.
    Blessings in abundance,
    All the Best,
    & ENJOY!

    Art . . . . Carlisle, PA . . USA

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width