+ Reply to Thread
Results 1 to 28 of 28

UDF to capture change in cell values

  1. #1
    Registered User
    Join Date
    03-07-2011
    Location
    Toronto, Canada
    MS-Off Ver
    Excel 2003
    Posts
    55

    UDF to capture change in cell values

    I have created a UDF to display "Success" (to keep this simple) every time one of the cells in the range D1:D4 changes.

    However, 3 out of 4 of the cells contain real-time data that is refreshed every 1500 milli-secs and so every time the cells refresh the function triggers the MsgBox to display even though the values haven't changed. I only want the MsgBox to display if the values in those cells change.... can anyone help, I have spent the last 3 days trolling the net for a resolution but to no avail?

    =Trigger(D1:D4)

    Please Login or Register  to view this content.
    Appreciation in advance.

  2. #2
    Registered User
    Join Date
    11-10-2011
    Location
    Summit County, CO, USA
    MS-Off Ver
    Excel 2007
    Posts
    4

    Re: UDF to capture change in cell values

    I can't reproduce the problem, at least in Excel 2007. Every time i enter the same data in one of the D1:D4 cells I get no response, but if I enter something different, the "success" msg appears. How do you do your 1.5 sec refresh?

  3. #3
    Forum Expert
    Join Date
    03-31-2009
    Location
    Barstow, Ca
    MS-Off Ver
    Excel 2002 & 2007
    Posts
    2,164

    Re: UDF to capture change in cell values

    Try putting "Application.Volatile False" as the first line in your UDF().
    Volatile UDF()s are executed every time the sheet calculates.

    Another solution would be to have the UDF() check all the values with a copy of the values somewhere else in the workbook and if they are different then put the message up and copy the values to the copy of the values for the next refresh.
    Foxguy

    Remember to mark your questions [Solved] and rate the answer(s)
    Forum Rules are Here

  4. #4
    Registered User
    Join Date
    03-07-2011
    Location
    Toronto, Canada
    MS-Off Ver
    Excel 2003
    Posts
    55

    Re: UDF to capture change in cell values

    Thanks for responding, I've tried Application.Volatile (false) but it didn't work and I can't cache or copy the data elsewhere to compare the changes because I need the function to work across many rows and data will be changing on different rows periodically so it will always be different.

    Any other suggestions?

  5. #5
    Registered User
    Join Date
    03-07-2011
    Location
    Toronto, Canada
    MS-Off Ver
    Excel 2003
    Posts
    55

    Re: UDF to capture change in cell values

    I'm using a third party add-in that provides the real-time data and the setting on the refresh is 1500 millisecs. It's definitiely the real time data because if I remove the input from the function cell for these 3 cells the function works only when I go in manually and change the value of the fourth cell.

  6. #6
    Forum Expert
    Join Date
    03-31-2009
    Location
    Barstow, Ca
    MS-Off Ver
    Excel 2002 & 2007
    Posts
    2,164

    Re: UDF to capture change in cell values

    I don't think you put "()" around the work "False" in the volatile statement.
    Put "()" around the parameters when you want to return a value.

    I don't understand why you can't make a copy of the data.
    I also don't understand why it's a problem that the data is always different. Isn't that what you're looking for?

    Just so were are on the same page.

    Please Login or Register  to view this content.

  7. #7
    Forum Expert shg's Avatar
    Join Date
    06-20-2007
    Location
    The Great State of Texas
    MS-Off Ver
    2003, 2010
    Posts
    40,678

    Re: UDF to capture change in cell values

    You could cache them locally:

    Please Login or Register  to view this content.
    If you used a lot of these, you'd bring the workbook to its knees.
    Last edited by shg; 11-18-2011 at 07:28 PM.
    Entia non sunt multiplicanda sine necessitate

  8. #8
    Registered User
    Join Date
    03-07-2011
    Location
    Toronto, Canada
    MS-Off Ver
    Excel 2003
    Posts
    55

    Re: UDF to capture change in cell values

    I would use hundreds of these and I need to avoid resource strain on the workbook. Thanks for the input though. I am seeking a way to disregard the data refresh thats triggering the function and just trigger on change in values.

  9. #9
    Registered User
    Join Date
    03-07-2011
    Location
    Toronto, Canada
    MS-Off Ver
    Excel 2003
    Posts
    55

    Exclamation Re: UDF to capture change in cell values

    Maybe I didn't explain the scenario as clearly as I could have, hopefully this helps.

    I will have the same function name on each row that will read in four fields of data on the corresponding row if any of the values change. Ie. =Trigger (D3:G3), =Trigger(D4:G4), =Trigger(D5:G5), etc.

    http://www.designcymru.com/images/example.jpg

    If a field on row 3 changes the function will pull in the values of those fields for me to do something specific with them. If I copy the values from row 3 to compare them next time I get a change and then a value in row 5 changes it will pull in a seperate set of data and of course it will be different. If I somehow store the data by each line to compare against the next time it will be very resource intensive on the workbook given I need this function to cover 1000+ lines.

    I tried Application.Volatile (False) as one of the first solutions but this doesn't work with the real time data refreshing in these cells every 1500 millisecs. This is my real issue, initiating the function on a row when one of the correspinding cells it's watching on that row actually changes value.... instead of the functon triggering across 1000 rows every 1500 millisecs.

    Hope this helps...

  10. #10
    Forum Expert
    Join Date
    03-31-2009
    Location
    Barstow, Ca
    MS-Off Ver
    Excel 2002 & 2007
    Posts
    2,164

    Re: UDF to capture change in cell values

    What you're saying is that you only want to trigger a UDF() if a value actually changes to a different value, not if it changes to the same value.

    I've never heard of a way to tell Excel to not trigger a UDF() if the new value is the same as the old value. As far as I know you have to store the old value and compare the new value to the old value.

    The UDF() could be made faster by having it trigger just once for the entire 1000 rows and keep the old values in memory instead of on a worksheet. So at least it doesn't take the time to save the values to disk.

    Please Login or Register  to view this content.
    Last edited by foxguy; 11-18-2011 at 11:25 PM.

  11. #11
    Registered User
    Join Date
    03-07-2011
    Location
    Toronto, Canada
    MS-Off Ver
    Excel 2003
    Posts
    55

    Re: UDF to capture change in cell values

    Hi foxguy,

    You'll have to excuse me, my VBA skills leave alot to be desired. I've spent some time looking at this and I think the best way would be to create a 2d array with 3 columns that will store the data in memory that I can compare against:
    1st col = index (can be derived from Application.ThisCell.Row)
    2nd col = YesNo (1st item in array I read in when function triggers)
    3rd col = Price (2nd item in array I read in when function triggers)

    Could you help me write some code to do the following please?

    Create 2d public array with 3 cols and 500+ rows (can this be dynamic?)

    Function Trigger (theParameter As Variant)
    Dim vArr As Variant
    Dim Index As Integer
    Dim YesNo As String
    Dim Price As Double
    vArr = theParameter

    'Assign row number as unique index number
    Index = Application.ThisCell.Row
    'Assign Price as second item read in from variant arrray
    Price = vArr (1, 3)

    With 2d array
    If Index exists in col1 of 2d array Then
    If YesNo <> corresponding yesno in col2 of 2d array Then
    MsgBox "YesNo different"
    yesno in col2 of 2d array = YesNo
    ElseIf Price <> corresponding price in col3 of 2d array Then
    MsgBox "Price different"
    price in col3 of 2d array = Price
    End If
    ElseIf Index does not exist in 2d array Then
    Create Entry in 2d array with Index(1), YesNo(2), Price(3)
    End If

    End With

    End Function

    Much appreciation for any help on this in advance.

  12. #12
    Forum Expert
    Join Date
    03-31-2009
    Location
    Barstow, Ca
    MS-Off Ver
    Excel 2002 & 2007
    Posts
    2,164

    Re: UDF to capture change in cell values

    I don't think this will work completely the way you want.
    Please go back and put code tags around your code, and indent between "If...End If", "For...Next", "With....End With", etc. like this:
    Please Login or Register  to view this content.
    This makes it easier to read and shows where each block of code starts and ends.
    This will allow you to look more critically at your code to see where there may be errors in your logic.

    At first glance:
    1) You Dim YesNo as string, but never assign a value.
    2) theParameter will probably be a single cell passed to the Function. Assigning a single cell to a variable doesn't make an array.
    3) the 1st time the Function is called the arrays will be empty so there is nothing to compare to. So you will want to create an array BEFORE the Function is called the first time and possibly use an "Undo" if it's empty when it's called in order to allow you to create the array.
    4) Arrays can only be dynamic in the last dimension. I would initially advise setting up the array in the Workbook_Open() event like this vArray1 = Sheets1.Usedrange, except that would make the # of rows fixed but allow you to add columns to the array, so you would want to transpose it so that the columns are fixed and you can add rows to the array.


    What you're doing is possible, and you're in the ballpark of a way to do it.

    I'll wait for the refined code (with code tags and indents)

  13. #13
    Registered User
    Join Date
    03-07-2011
    Location
    Toronto, Canada
    MS-Off Ver
    Excel 2003
    Posts
    55

    Re: UDF to capture change in cell values

    Apologies, here's my next shot. theParameter will pass in the 2 variables I need as an array from a range so the function will be: =Trigger(D1:E1)

    I was thinking that given the array won't be populated the first time the function is triggered on each row, if an entry with the index (Row) doesn't exist then it will create it. As you can see from my requests in the code below, I need help on the global array front and as you suggested to initialize it before it can be used.

    Please Login or Register  to view this content.

  14. #14
    Forum Expert
    Join Date
    03-31-2009
    Location
    Barstow, Ca
    MS-Off Ver
    Excel 2002 & 2007
    Posts
    2,164

    Re: UDF to capture change in cell values

    It occurred to me that when you open the file it will run the function at least once for each instance of the Function() in your worksheet.
    So no need to initialize the vars before running.

    I'm just giving you the skeleton here for you to study and figure out what is going on. This can get a bit complicated and you will probably want to add on to it in the future. So you need to understand what is happening.

    I did not test this. I left that for you.

    Please Login or Register  to view this content.
    Last edited by foxguy; 11-22-2011 at 09:12 PM.

  15. #15
    Registered User
    Join Date
    03-07-2011
    Location
    Toronto, Canada
    MS-Off Ver
    Excel 2003
    Posts
    55

    Thumbs up Re: UDF to capture change in cell values

    Thanks for this foxguy, I've been looking at this all morning but it seems it's not populating the array correctly.I had 2 cols of values for 50 rows and then the function in the 3rd col. It returned the time nicely and updated every time I manually changed a value but I couldn't get it further than initializing the array to test comparing the values.

    I placed a break at Trigger = vArr to see how the array was populating in the Locals window and this is what it looked like:
    Screenshot of Locals window
    Also, is the code to compare rCells2Check values versus corresponding values in the array accurate?
    Please Login or Register  to view this content.

  16. #16
    Forum Expert
    Join Date
    03-31-2009
    Location
    Barstow, Ca
    MS-Off Ver
    Excel 2002 & 2007
    Posts
    2,164

    Re: UDF to capture change in cell values

    "Trigger = vArr" was commented out. I left your code in the macro so you could compare your code with code that works (hopefully).
    "Trigger = vArr" is trying to put an array into a Date variable for the Function to return. That will always crash with a "invalid type" (or something similar) error.

    Didn't catch a bug in my macro

    Please Login or Register  to view this content.
    The old code was always reinitializing the entire array every time (which erases all the data in it).

    I don't see any point to these lines:
    Please Login or Register  to view this content.
    You never use them anywhere.


    You comparison looks fine. I would put into the message the address of the cell that triggered it, so the user could easily find the change.

  17. #17
    Registered User
    Join Date
    03-07-2011
    Location
    Toronto, Canada
    MS-Off Ver
    Excel 2003
    Posts
    55

    Re: UDF to capture change in cell values

    Thanks foxguy. YesNo/Price are values I want to use when I get the msgbox displaying if values are different, getting a little ahead of myself there.

    I created cellChanged = rCells2Check.Cells.Address to include in the msgbox.

    I've tested the sheet and the array populates with the right # of cols perfectly, then when I change a value it takes the right route through the Else below but doesn't compare the values at all. I've spent some time looking at this but it seems this code should work. Am I missing something?

    Please Login or Register  to view this content.

    Also, it seems the function sometimes reads in NA/Empty values and then the actual values if a cell value changes. I've read this is common so I was planning on adding the following code to check each value in range separately and exit if this is the case right off the bat. Is this the most efficient way to do this?

    Please Login or Register  to view this content.

  18. #18
    Forum Expert
    Join Date
    03-31-2009
    Location
    Barstow, Ca
    MS-Off Ver
    Excel 2002 & 2007
    Posts
    2,164

    Re: UDF to capture change in cell values

    Quote Originally Posted by chris1983 View Post
    Please Login or Register  to view this content.
    What if only 1 of the cells in Cess2Check will be N/A. Do you want the values in the rest of cells to be available for the next comparison.

    I didn't look at the entire macro. I just looked at the comparison code. I didn't even notice that you weren't cycling through the cells.
    I also failed to notice that you're not putting the new value into the array for the next change to check against.

    I'm writing this on the website. I'm not testing this, so if there is a typo or oversight, I hope you catch it.

    Please Login or Register  to view this content.

  19. #19
    Registered User
    Join Date
    03-07-2011
    Location
    Toronto, Canada
    MS-Off Ver
    Excel 2003
    Posts
    55

    Re: UDF to capture change in cell values

    Thank you so much foxguy for all your help on this. You're right I would need to update the one valid value if one of the values in the range was NA/Empty, what's the easiest method of doing this? I also thought if I checked these values right at the start of the function and they are both NA/Empty I could exit right away to save time given I need this function to work across 1,000 rows. Or wouldn't I notice a time difference? Minimal latency on updates is critical for me given the potential to expand rows further than 1,000...

  20. #20
    Forum Expert
    Join Date
    03-31-2009
    Location
    Barstow, Ca
    MS-Off Ver
    Excel 2002 & 2007
    Posts
    2,164

    Re: UDF to capture change in cell values

    The UDF() is currently checking every cell in the range passed to it. Checking all the values first in order to exit the UDF() immediately is pointless IMHO. It would then lengthen the time it takes to look at them again if they aren't all N/A. The amount of time it takes to put a value into an array can't be measured by your computer because it's so fast. I would bet that having to put 500 values into an array takes less than 1 millisecond for them all.

    The UDF() will be triggered in any cell where the parameters to the UDF() change.
    If the UDF() is called with =Trigger(A3:B3), it will be triggered any time Excel thinks that A3 or B3 changes.

    If you have 500 rows with that formula (the bottom one being =Trigger(A502:B502) and Excel interprets it as a change when a cell is changed to the same value, then the UDF() is going to be triggered 500 times every time.
    If in fact that is the case, it would probably be faster to just have 1 formula =Trigger(A3:B502) and you would obviously have to change the UDF() to check 500 rows. I feel confident that it would take less time to call the UDF() 1 time and check 500 rows, than to call the UDF() 500 times and check 1 row each time.

    I believe it is possible to set up formulas to determine if cells change values and then only call the UDF() for the rows that actually change value. It would trigger one of Excel's internal functions (which are always faster than a UDF()) 500 times, but it would require the values to be on the worksheet instead of in an array in the UDF().

    I also just occurred to me. If you put a Msgbox into the UDF(), it will stop until the user hits a key. If 500 rows do change value, the user would have to hit a key 500 times before the data gets refreshed. You might consider just putting the address of the changed cells back into the cell with =Trigger(...) in it, and use conditional formatting to highlight the cells that have changed.

    A consideration: Excel can do the comparisons faster than VBA. It could be offset by the time it takes to put the values back on the worksheet for Excel to compare, but if it's going to end up checking 500 rows all the time, it might be faster to put the values back on the worksheet and let Excel compare and just highlight the cells that are changed.

    I know this probably complicates things, but they are all things that you should consider.

    If I was in your position I would time the UDF() and print the results for all the different ways to accomplish what you want.
    The "TIMER" staement counts how many ticks since MidNight (1 tick is approximately 1 millisecond)

    Please Login or Register  to view this content.
    This would tell you how many milliseconds it takes to run the UDF(). Try it by checking what the time using arrays vs time putting it on the worksheet, checking 500 rows in 1 call to the UDF() vs checking 1 row in 500 calls to the UDF(), etc. It's a lot of work, but if this is something you're going to use for a long time, it's worth figureing out the fastest method.

  21. #21
    Forum Guru romperstomper's Avatar
    Join Date
    11-04-2008
    Location
    A1
    MS-Off Ver
    Most
    Posts
    12,302

    Re: UDF to capture change in cell values

    Have you tried using the ID property of the cells? In the function, iterate each cell and test value against ID; if different, update the ID and process; if not, do nothing.
    Remember what the dormouse said
    Feed your head

  22. #22
    Forum Expert
    Join Date
    03-31-2009
    Location
    Barstow, Ca
    MS-Off Ver
    Excel 2002 & 2007
    Posts
    2,164

    Re: UDF to capture change in cell values

    I never new there was an Cell.ID property. You learn something new every day.

    Chris;
    This sounds promising. Use the ID property instead of an array in the UDF(). I can't imagine that it's enough faster to make a difference, but it looks like it would be much easier to understand and program.

    In fact I think I'm going to look into using it in all my workbooks. It would make it easy to Undo changes I don't want to allow.

  23. #23
    Registered User
    Join Date
    03-07-2011
    Location
    Toronto, Canada
    MS-Off Ver
    Excel 2003
    Posts
    55

    Re: UDF to capture change in cell values

    Thanks for the ideas foxguy, this is the for the long term so it'll be worth investigating. If I compared the full 500 lines once versus each line 500 times how would I identify the row that changed, I've put some thought around what that code might look like but I'm just not getting it.

    I still see the function pulling in NA values so this code doesn't seem to be working and this is a critical piece. It seems to continue through to the ElseIf statement and display the msgbox even with one of the cells in the range having an NA value, so I'm assuming what I have below is inaccurate?
    Please Login or Register  to view this content.
    I'm curious to see what romperstomper's suggestion yields. Could you elaborate on how I would iterate each cell and test each value against ID please?

    Much appreciation in advance.

  24. #24
    Forum Guru romperstomper's Avatar
    Join Date
    11-04-2008
    Location
    A1
    MS-Off Ver
    Most
    Posts
    12,302

    Re: UDF to capture change in cell values

    It would be:
    Please Login or Register  to view this content.

  25. #25
    Registered User
    Join Date
    03-07-2011
    Location
    Toronto, Canada
    MS-Off Ver
    Excel 2003
    Posts
    55

    Re: UDF to capture change in cell values

    Apologies romperstomper I meant to direct this comment in my previous code to you, it didn't come across that way...

    I'm curious to see what romperstomper's suggestion yields. Could you elaborate on how I would iterate each cell and test each value against ID please?

  26. #26
    Forum Expert
    Join Date
    03-31-2009
    Location
    Barstow, Ca
    MS-Off Ver
    Excel 2002 & 2007
    Posts
    2,164

    Re: UDF to capture change in cell values

    quick answer. This will get you started.

    Please Login or Register  to view this content.
    You seem to be saying that you don't want the value N/A to remain in the cell. Do you want to replace the N/A with the old value? If so, then figure out what to check in order know to replace it with .id.
    Last edited by foxguy; 11-24-2011 at 09:23 PM.

  27. #27
    Registered User
    Join Date
    03-07-2011
    Location
    Toronto, Canada
    MS-Off Ver
    Excel 2003
    Posts
    55

    Re: UDF to capture change in cell values

    Hi foxguy, I don't see how this function is storing/comparing values in each cell. The rCell.ID (ie. $A$1) is always going to be different to the rCell.Value (ie. 256) so this would prompt me with a msgbox for every cell in the range when I make a single change. Can you please shed some light on this alternative because I'd really like to understand how this method would work.

  28. #28
    Registered User
    Join Date
    03-07-2011
    Location
    Toronto, Canada
    MS-Off Ver
    Excel 2003
    Posts
    55

    Re: UDF to capture change in cell values

    RomperStomper, I have been using foxguys suggestion for the last month and reaching 1000+ lines using this UDF and it's doing the job but I would really like to explore your suggestion of using ID property of each cell to compare values. I'm thinking in order to make this solution scalable to 2000+ lines I need to find a more efficient method. Can you please elaborate on how I can acheive this?

    Thanks

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Bookmarks

Posting Permissions

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

Search Engine Friendly URLs by vBSEO 3.6.0 RC 1