I have a 60mb excel file that has all of the "sins"... Array formulas, VBA and conditional formats. It crashes all the time and it's now being suggested that it's too big. There are about 20 worksheets and 3 of them are 15mb in size and each have about 35,000,000 active cells. Is this why the sheet crashes?
Yea I have this problem also.
This is a compilation of hat works for me. Some of this may be relevant, some may not.
Turn off automatic calculation. If you are desperate about this, then turn it off while doing the rest of the list but turn on afterwards
Make a backup. Everytime something on this list works, make a new backup. Excel has no brain, make sure to use your own.
Remove empty-but-not-empty cells... Sometimes, for a number of reasons, excel finds it necessary to keep track of all possible rows and columns.
I fix this by recreating whatever chart I have made by copying the specific areas that are needed on new sheets and then delete the old one and rename the new one to match. Search/replace will fix formulas afterwards if they get buggered. You can also mark the rows/cols and right-click -> delete rows/cols but that may cause a total freeze so I prefer the former method.
Get rid of the array formulas. Seriously, they can in 90-something % of the time be replaced by a cleverer sumproduct, sumifs or index(match()) formula or by adding columns or doing things in 2 steps. They are resource hogs. Leftovers from a different age. The only time I accept arrays is when I know I have exhausted all possibilities.
Very important, save the files as x64 binary formats for the files (.xlsb). Do not use the "compatibility" format (.xlsx) and for the love of god, do not use regular .xls
Move all graphics to separate sheets, and better yet, separate files. Mirror the result data via vba, copy paste, whatever to separate files and have your conditional formatting, images, graphs, progress bars, gantts, whatever there.
I hope it's not inappropriate to post this.
After some stalling and perhaps some skepticism, I replaced all of the array formulas in my sheet. There were approximately 1,500,000 cells affected by array formulas and I didn't relish the thought of redoing this. BUT WHAT AN UNBELIEVABLE DIFFERENCE! The sheet now runs faster, better and very reliably! I'll never use an array formula again. Thank you!!
Related
I need to provide a current list of files in a directory in an Excel workbook and everything is working as required, just too slowly. I really only need the list to check it is current once upon opening the workbook. It takes around 11 seconds to do this which is acceptable but the problem is it keeps rechecking this every time I carry out even minor edits to the workbook (I guess due to the fact that it is brought in as an Excel table). I determined the lag in my workbook using the rangetimer() function that is provided and it is the only thing taking a long time to calculate. I should also state that the table containing the list of files is finally used in a cell on another worksheet to provide a data validation drop-down list but don't believe this is really the issue.
I did some Googling on reducing Excel calculation times and discovered that there are some Excel functions that are definitely culprits for increasing calculation times (described as volatile) and three of these (NOW,INDEX and ROW) are used in providing the functionality I would like in this part of the workbook.
I have tried two solutions so far:
1. Force Full Calculation set to True in VBA properties window
2. Switched calculations to manual. I set this back to automatic once I identified that this part of the workbook was the issue as I don't want manual calculation generally.
The formula I have in the 'refers to' box of the named range (TutorFileList) is:
'''=FILES("\O008DC01\Shared\Tutor Qualifications*")&T(NOW())'''
The formula I have in each cell of the excel table is:
'''=IFERROR(INDEX(TutorFileList,ROW()-1),"")'''
What I would like to have is the ~11secs of calculated time to find these files reduced down to just one check of the networked directory rather than it taking 11secs of automatic recalculation every time the workbook is modified.
If there is a more efficient way to achieve what I am doing I am prepared to redesign things but I do need the functionality of a drop-down list of files in the specific directory in a cell.
Many thanks for assistance from anyone on this.
I have resolved my issue by reducing the number of rows back to around 200 instead of 500 rows. This brings the calculation lag back to about a second which I can live with.
I've got a collection of about 40 Excel worksheets. They store information about the number of hours that people have spent working on different projects, with dates across the top row from left to right and project names down the first column. Each member of the team has their own separate worksheet.
I'm making a new worksheet that will add up the number of hours each person has spent on a specific project.
I'm using this formula to add up all the numbers in a particular range of a linked file:
SUM(INDEX('S:\path\to\folder[Username_2017.xlsx]Daily'!G:JG,JOB_ROW,0))
JOB_ROW is the row containing the numbers I want to add up. Columns G:JG cover 1 Jan - 31 Dec. Username_2017.xlsx is different for each of the 40 people.
The problem is that the formula only works if I create it by hand. I can't find any way to use a dynamic reference to the filename, which gets very tedious with 40+ files to reference. I thought this might work:
SUM(INDEX(INDIRECT(C3),JOB_ROW,0))
...where C3, C4, C5 etc. would contain automatically-generated filenames and references. But it doesn't work. I get #REF!. And Excel doesn't prompt me to link the files -- which suggests to me that it will never work this way.
I've also found that even when the spreadsheet is working properly with the manually-entered formulae, if I save it and re-open it then Excel tries to be helpful by stripping out the formulas and replacing them with the text #REF!.
Is it possible to do what I'm trying to do? Or do I need to learn some VBA?
I should point out that I've largely avoided using Excel in my career so far -- so if there's a better way to achieve this then I'd love to hear it.
Thanks in advance for your help.
ian0411 gave the simple answer to this question in the comments above: the answer is "you can't do that".
If he wants to post that then I'll accept it as an answer -- but for the benefit of anyone else reading this question and looking for alternative options, here's what I tried and what worked:
VBA
I wrote some very simple VBA using GetObject() to open and read from each of the workbooks. It worked, but a) it was very slow, and b) it seemed to keep all the files open as long as Excel was running, which caused other problems. It also crashed a lot.
I gave up on VBA.
Automating the filename replacement
The next option I tried was to have a column of filenames in Excel, with a column next to it containing the formula that I wanted to run on each file. Instead of putting the linked filename in the formula, I put a unique placeholder ('XXXXX' or whatever).
Then I made a little macro that (for the currently selected row) did a search and replace across the row to change 'XXXXX' to the filename in column A. I had to run the macro 40 times to cover each file, but I only had to do that process once. When I add a new file to the list, I'll just add a new line, copy the formulas, and update the filename.
I've now got a spreadsheet which works perfectly when the linked files are closed, and which doesn't rely on VBA.
Perhaps if my VBA skills were better I could have written something less flaky -- but doing it all with INDEX() seems like the fastest, most elegant, and most reliable solution.
I have a very difficult issue I have been trying to solve for a few days, I would very much appreciate some help as I have tried to research this issue completely already.
One one sheet I have a database (18 columns and 72,000 rows) in 32 Bit Excel 2010, so its a large database. On this sheet I also have some entries to auto-filter some columns, as well as an advance filter. When I run the Advanced filter, the data filters in 1 second exactly. If I run an auto-filter, (via vba macros) then run advance filter afterwords, the Advanced filter takes 60 seconds to run, even after turning autofiltermode to false. Here is what i have tried but no luck
Removing all shapes on the sheet
THere are no comments on the sheet so none to removed
Removing all regular and conditional formatting
Turning off auto-filter mode
Setting all cell text on the sheet to WrappedText = False
Un-protecting the sheet
Un-hiding any rows and columns
Removing any sorting (.sort.sortfields.clear)
What else could cause this code to run 60 times slower but only after autofilter has previously run on the sheet, and how can i return it to that state? Any and all help would be greatly appreciated
In my case I was programmatically creating named ranges for later use, and these named ranges used the .End(xlDown) functionality to find the end of the data set. For e.g:
Set DLPRange = .Range(.Cells(2, indexHeaders(2)), .Cells(i, indexHeaders(2)).End(xlDown))
DLPRange.Name = "DLPRangeName"
... which creates a column range from the starting cell to the end of the document in my case. Originally this 'bad' way of finding the range went unnoticed because the file format of the workbook was .xls and maxed out at 65k rows. When I needed more I forced it to create a workbook in .xlsm format, which has ~1M rows. The filter ran on the whole column even though the huge majority of it was empty, resulting in the huge time overhead.
tl;dr: you've tricked excel into thinking it has a huge amount of data to filter. Untrick it by checking and making sure it's only filtering the range you think it should be filtering.
After trial and mostly lots of error I was able to find a solution. I determined that almost any action, even without auto-filter would cause this slowdown, and I felt that simply this was a memory issue for Excel with all of that data (even though it ran find sometimes, the 'cache' I'm guessing would fill up and then run slow.
So what I did was use a new and temporary workbook in which the Advanced filter would add the data on filter. I then took this data and copied a portion of it back into my workbook. Then I closed this temporary workbook without saving it. This also brought the code run from 1 second to .3 seconds and I never got the slow Advanced filter run time, regardless of what code I ran or what I did on the original workbook.
I posted this so if anyone else had a similar issue they might use this as a solution for large amounts of data.
A little late, but recently I had the same issue with a not so large database (4000+ rows, 70 columns) and solved it, so just sharing.
In my case, problem was with wrapped text in data range. Setting WrappedText to false as you said helps is not enough, you need to replace Chr(10) in the range you are filtering. Huge difference.
Using Excel/Word 2007 I'm trying to copy multiple selections from Excel to Word. When I paste it into Word it's as if it ignored the break in the ranges and just pastes a range that includes everything I was trying to leave out.
For instance if I intend to copy/paste "A2:D4, A6:D7, A10:D11" what is actually pasted in word is "A2:D11", so it's ignoring the breaks in the selections. I can't seem to find any documentation on this issue anywhere. If someone knows anything I'd really appreciated it. I know I'm selecting the ranges properly because if I copy and paste the multiple ranges within Excel it works like it should.
The actual issue is that I have these actions automated in a macro and I'd really prefer not to loop through the individual ranges because they're stored in a dictionary and it would be just a real hassle. Despite that, it seems weird that I can't even accomplish the task manually.
I've done quite a bit of digging and can't seem to come up with anything. I thought about using the Office clipboard but you can't paste tables as an RTF. It doesn't seem like there are any options when pasting with the office clipboard.
AFAIK it doesn't seem possible and I've tried to exhaust all my normal avenues of knowledge before posting here. If anyone has ever just experienced this it would be comforting to know I'm not alone.
I don't know how to prevent that from happening, but you could potentially work around it by pasting your non-continuous selection into a continuous region in a new, temporary sheet/workbook, then copying the continuous region from the temp sheet/workbook into word.
a bit of a hassle, yes, but it should get the job done.
I want to print a row in Excel.
One row contains data for one project.
I want to print one row on one page nicely formatted. Meaning the value of one cell is the header and should be printed fat and centred, the other values should also be placed at fixed positions on the page.
Is this with VBA possible? When I was searching for this problem I only found results for printing a worksheet or a table or parts of it, but no results to use the values of the cells and formatting them.
Thanks in advance
As the other answers indicate, it is certainly possible in Excel VBA, but it is not really Excel's strong point.
What would typically be done to obtain the result you seem to be after is use a fully formatted Word document with fields that are then filled in with values from an Excel worksheet. You can even cheat a bit and use the Mail Merge \ Letter wizard to set everything up.
If you do want to do it all in Excel, you can find instructions and an example VBA macro here:
http://www.tek-tips.com/faqs.cfm?fid=4223
Template is a good way to do. With a macro there's better performance where it avoids the usage of volatile functions such as INDIRECT() However again it depends on how many volatile functions your worksheet carries.
Yes, it is possible when you use the Styles in excel. I know you can do Font formatting quite easily. Not sure about indenting it, but worth a try.
If style doesnt support it (it might in Excel 2010), you can always indent it via VBA (record a macro when you indent the values , it should look like this):
Selection.InsertIndent 1