Check values are the same within a certain time period - vba

I have two workbooks with identical sheets and I need to test whether the data they are getting (from different sources) is identical or within a certain threshold. This, I am already able to do fine. I create a third workbook which calculates the difference between the two.
However, the issue is that one workbook updates seconds before the second which means that if a cell gets two quick updates my calculations would lag behind.
So what I was thinking is that I make a note of the cell value in workbook 1 (the faster updating workbook) and if at anytime up to x seconds after workbook 2 cell has the same value as noted, they are good.
...but how would I go about this, is VBA even the best tool for this?
Any ideas?

using timestamps and vba - or maybe even conditional formatting and some good formulas - could solve this for sure.
However, without anything to work on, it is quite a big step to present you a solution.
Basically you would just create timestamps (internally as variables, or during the import process in cells) and then compare your values, after your threshold ran out. If the values of your compared cells still match, then it's ok.
However, this is all quite dependant on how you solved your dataimput and comparison.
My basic feeling, after I red your question was: "why wouldn't you just decrease your update rate of your calculation?"
Another idea: just use an indicator cell, switching between 1 and 0 or so, to indicate, if an update already happend - so, if you compare, you compare value+indicator. which is basically using timestamps without time.

Related

Do graphs slow down my calculation speed in a large excel file?

I am working with a huge excel file that is updated with a set of macros. In the excel file there are also a large number of graphs to ensure easy output checks.
However, when I re-calculate the workbook it is extremely slow.
My question is: Do these graphs contribute to slowing down the calculation of the model? If so, is there a quick VBA way to only update graphs at the end of the overall calculation?
Without seeing your workbook this is hard to answer.
Most likely, it is not the charts (is that what you call "graphs") that are slowing down the recalc, but inefficient formulas.
Check the chart data sources. If they point to worksheet cells, then all is good. If they point to named ranges / named formulas, then check what these formulas are.
Recalculation is affected by
volatile formulas like Today(), Now(), Indirect(), Offset() and a few others
inefficient formulas that needlessly repeat calculations that have already been performed, typically done in running totals
And example of this would be
=Sum(A$1:A2) copied down, like in this screenshot
In each row, the calculation starts in row 1 and goes down to the current row. This is a waste of effort.
A much more efficient formula is in column C, where just the value from the row above is added to the value of the current row.
=SUM(C1,A2)
These details can make a heck of a difference.
For more information you may want to refer to Charles Williams' site http://www.decisionmodels.com/calcsecrets.htm and the pages linked from there.
It's a complex subject and can probably not be addressed in a simple answer to a seemingly simple question.

Macro to update column data with vlookup result

I have two spread sheets, Sheet1 & Sheet2.
Sheet2 will be a paste of a lot of information received from a third party with a unique ID in column B, I’m currently using vlookup but the spread sheet is getting very large and taking a long time to load up and save.
In sheet 1 I'd like to use a macro to insert the vlookup result from a MACRO matching the unique ID in column B and displaying the value of column c from Sheet2.
Hope this makes sense, thank you!!
Tried a lot:
Sub UPDATE()
Dim s1 As Worksheet, s2 As Worksheet
Set s1 = Sheets("Sheet1")
Set s2 = Sheets("Sheet2")
v1 = s1.Range("A2")
v2 = s1.Range("B2")
s2.Activate
For Each r In Intersect(ActiveSheet.UsedRange, Range("B:B"))
If r.Value = v1 Then
r.Offset(0, 1).Value = v2
End If
Next
End Sub
If you can post a non-question in the question field, then can I post a non-answer in the answer field?
The help you need right now is not the help you kinda, sorta, but not really asked for. You just don't know it yet.
If I stop judging your intent between the lines and ignore your insulting response to a genuinely helpful comment. If I take the time and energy to focus on your problem and semantically transform your demand into a question. Then you still will not get what you asked for.
I shall demonstrate.
A large workbook with 2 sheets loads and saves slowly. Presumably because of its size and numerous vloookup functions. To improve performance you want a macro on sheet 1 to “insert the vlookup result from a MACRO” on sheet 2.
This may surprise you. If a formula is already optimized then replacing it with another formula will not improve performance. Even if that formula is a vlookup and even if that vlookup is placed by a MACRO. In fact, it will be slower because you're still calculating the vloookups and now you've added the overhead of running the macro on sheet 1 and the MACRO on sheet 2. Seems to me like you might get a performance boost by changing your calculation settings to calculate before save and do not refresh or calculate when opening. That won't improve your save time but opening and working with document should be faster.
That's an answer you didn't ask for but it's weak and really doesn't do much to get to the root. I'm really trying to help so I won't stop yet I'll dig through the code you shared and focus on the pieces where you think the problems are. Oh, you didn't say where they could be. No big deal, it's a short block and I'm almost VBA literate, I'm sure I won't have any issues fixing bugged code as I step through it in my head without access to test data or your runtime environment. Piece of cake!
Umm… what are you trying to do? I think I understand what you said you want; but I don't see how you actually went about doing it. I'll work with what you gave me but it isn't much so I hope you don't have high expectations.
Sheet 1 and 2 are set. 2 is activated and this sub starts working with it; therefore, this must be the sheet 2 MACRO. How does this interact with the sheet 1 macro? Are you certain there's no problem with that one?
Hrmmmm, I've read a little about the speed of intersection. If i recall correctly, it's supposed to be quite fast, that might be a good choice. I'll have to remember that. Uh, B:B, the whole column? You can often gain performance by narrowing constraints, but I am not certain in this case. Maybe intersection is a of short circuiting every row that follows, i should look into that.
I have to assume v1 and v2 are variants because they aren't declared and no information is given regarding option explicit or publicly scoped variables. You have to be careful variants because they can change type and cause you to throw errors all day. Especially if your code isn't clear enough to identify them on sight. Case and point, you assign 2 variants equal to a range, is this intentional or did you forget the word set? Further down you assign the value of a range to the same variant leaving me to guess about your intent.
Does your data use strings? If it does then value2 should be faster than value.
I'm confused about your loop I don't know why you have it or why you're do what you do. You said you have vlookup results pasted in B - so it makes sense that you read it. But why in a loop? You calculated a valid range, why not write if to an array in one step instead of potentially hundreds or thousands? Why are you writing to column C in sheet 2? I would have expected sheet1.
Wait, that's it? That's all your code does? They're must be something else because there is no way for me to get from where you are to where you said you want to be without acting like your personal code writing service.
So there it is. In detail. A genuine attempt to give you what you asked for. How much closer to your goal are you now that I've spent more than 2 hours offering my hand?
Probably not much.
Unsurprisingly the most helpful piece of information, the one that will get you the closest to your goal, was given to you in the first comment and it reflects poorly on you to respond in the manner you did.
From my perspective, it looks like you haven't figured out what you need to know. I'd start with with option explicit. Then transferring data between sheets. Then using ranges with arrays. That should get you to a point where we can actually help you. That's 3 topics and 1 of them is a 20 second read.
Good luck, and try to lose the attitude.

Variable parameter vs hardcoding

I have a large complex spreadsheet with ~200 tabs. It opens/loads very slowly (upto 5 minutes) due to multitudes of formula calculations. I am trying to optimize the formulas so the spreadsheet will open/load faster.
One of the most frequent calculations is to multiply about 60 cells in each tab by a variable in 'Sheet1!B4' (Sheet 1, cell B4). I expect this value to change maybe once in a year or so, which would require updating all 200 tabs in at least 60 cells each.
Will it be better to hard-code the value, and take the hit for updating it once a year in all the affected cells in all the tabs?
Or is it ok to reference it in some way, which does not impact the performance, and preferably makes it faster?
Here are the three options I am considering:
Hardcoded value: =countif(C$10:C$30,$B60) * 10
Reference cell: =countif(C$10:C$30,$B60) * Sheet1!:B4
Use Named Range of a single cell: =countif(C$10:C$30,$B60) * PARAMETER_VAL
where PARAMETER_VAL is a named range referencing Sheet1!B4
Which of the above would be the fastest?
Is there any other way to make it faster, that I may be missing?
I don't think that any of the three alternatives will have significative difference on the spreadsheet performance because the reference / named ranges point to a cell with a fixed value.
Related Q&A
Measurement of execution time of built-in functions for Spreadsheet

How do I prevent unlocked cells from being selected/editable? (VBA)

I have a very specific question that I am looking for help in answering. I have been researching for hours and I feel like I am not able to find what I am looking for. Below is a quick overview of the criteria that my document must follow:
I am using Excel 2013
I will just be using rows for data input (instead of an excel object
table).
The very top/first row will act as my "column header".
This top row will have AutoFilter enabled.
THE DOCUMENT MUST BE PROTECTED (a must-have)!
I will be using VBA code
Now, the final issue I am having with finishing this document are the last two criteria points that I must have:
The first/top row (column headers) must NOT BE EDITABLE.
Each column must be able to SORT AND FILTER.
Now, in a perfect world, I would just "Lock Cells" for the entire first row that acts as my column headers and when I protect the worksheet I would make sure to check the "Sort" and "Use AutoFilter" boxes.
However, this option does not work because there seems to be an issue when I try to sort the data. If I just filter the data there is no problem, but when I try to sort a column in ascending/descending order I will get an error informing me that I can't sort locked cells while in Protected mode. This is because when excel uses the Sort function, it counts the header as part of the data that is being sorted (I found this out through my research) even though I really just want the data below it to be sorted.
I have been trying to brainstorm on how to get past this issue as well as researching different methods, and I am having trouble coming to a final conclusion. However I have narrowed it down to 2 possible solutions:
I want to be able to keep the cells in the first row officially unlocked to allow the AutoFilter's sort command to work as intended, but make it "behave" like the cells are locked when a user tries to make changes to it (AKA, make the entire row un-editable or un-selectable).
The other option would be to keep the first row locked but somehow have an event in VBA that can tell when a user tries to "Sort" the column, which will then temporarily unprotect the worksheet, follow through with the intended sort command, then protect the worksheet again (apparently though, upon my research there is no such event that can trigger off the AutoFilter's sort command alone).
These 2 solutions are the most logical I can think of based off my research, but if someone out there is an Excel genius and knows another way I am open to suggestions.
Thanks in advance for your help/suggestions,
Travo
Consider using two header rows. The top row would be protected and the second row would facilitate filtering and sorting of the data in rows 3 and below.

Unable to move / delete rows in shared workbook - Not enough resources

this one's a bit of a painful one so thank you for your help and patience with me.
We have an Excel spreadsheet that we use as a master file for our website products. As such there are quite a few sheets and quite a few products on each running along side some macros to provide some extra functionality (turning entered data into HTML for product page, etc).
My issue is that one of our most used spreadsheets has become a trouble in that it has some phantom formatting all the way down to the millionth-and-something row and all the way across, causing the last cell to be the very last cell possible.
The issue that has finally popped up as a result is that we can no longer move rows in, out or around the sheet (a required functionality) as it results in an 'out of resources error'.
I've tried:
Highlight all rows below used range to right-click> delete - Results in runtime error (from macro)
Highlighting large chunks of rows and using Clear All - Resulted in the 38MB file bloating to 380MB
Deleting a chunk of rows at a time - Maxed out at 1,000 before it caused Excel to crash
Moving to new spreadsheet - Broke all our macros (which I did not write and am not proficient enough to fix on a new sheet)
Disabling macros and trying the above options, only marginally more efficient but still out of resources
I'm at my wits end on this one and, while we can continue with most day-to-day functions, we will soon be completely unable to use this particular sheet as we need it at all.
I'm wondering if there might be a way to run a VBA script to remove these rows, potentially one by one? I've tried running a short script that went something like rows[960,1000000].Delete (forgive my terrible VBA markup), but this also resulted in not enough resources errors.
I'm wondering if there's anything like:
row = 960;
while(row<=1048576){row.Delete};
Continuing, the runtime error debug points me to the below if statement within the macro:
If Target.Count > 1 Then Exit Sub
Where Target is the variable passed to the sub.
Which strikes me as very odd because my (limited) understanding of VBA and IF's in general simply recognizes that 'if my selection is larger than 1 (row?), do not run this code..
Thanks again in advance.
Use this method only if you don't have any links into or out of the sheet that will get broken. Also might have Sql connections that might get broken. Might need to disable macros. There are many possible problems with this approach. Use at your own risk.
Note the exact "Name" and "(Name)" of the sheet; Look in the VBA code window at the properties for the sheet. "Name" is the name displayed on the worksheet tab. "(Name)" is the code name visible only in the properties window.
Make a list of range names on the sheet.
Copy the data to a new sheet.
Copy any macros to the new sheet.
Delete the old sheet.
Rename the "Name" and "(Name)" of the new sheet the same as the old one.
Recreate range names.
A better method if you don't have too many formats:
Disable macros and set calculation to manual. This avoids recalculating while doing your delete operation.
Select entire sheet and clear formats.
Delete all rows below your data.
Redo your formatting. Select entire column (not just used area) to apply format if applicable.
It is important to remove formatting on the entire sheet from A1 to the end. Otherwise you'll get the bloat you mentioned. Just that step may solve your problem. If not then proceed with removing all the rows below the data. This should not cause file size bloat.