Macro is too slow - excel

I'm fairly new to programming. And I'm not sure why the macro is running too slow (excel file is not responding).
full code
Have tried to simplify this
Worksheets("Sheet2").Select
Range("S1", Range("S1").End(xlDown)).Copy
Worksheets("Sheet1").Select
Range("K10").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone,SkipBlanks:=False, Transpose:=False
to this
Worksheets("Sheet2").Range("S1", Range("S1").End(xlDown)).Copy
Worksheets("Sheet1").Range("K10").PasteSpecial
but it's not pasting the values. I don't know what I did wrong.

your code is probably so slow since your range is huge (up to 50000) and it has to loop through it, which takes a great amount of time. Try rewriting your either using an dynamic range, or by avoiding using the loop function.

Related

Running Excel using VBA from another program

I am using vba in a CAD program to export data, sort the data, and add data. The following macro is exactly what I want excel to do. However I believe I am limited to having the CAD program tell Excel what to do through VBA. This macro copyies a formula and pastes it to all the populated cells below it in the column.
MACRO CODE:
Range("B1").Select
Selection.Copy
Range(Selection, Selection.End(xlDown)).Select
ActiveSheet.Paste
iLogic Version of Code:
oBook.WorkSheets(1).Name = "Order List"
oBook.WorkSheets(2).Name = "Cut List"
wSheet1 = oBook.WorkSheets("Order List")
wSheet2 = oBook.WorkSheets("Cut List")
wSheet2.Activate
wSheet2.Range("B1").Select
wSheet2.Selection.Copy
wSheet2.Range(Selection, Selection.End(xlDown)).Select
wSheet2.Selection.Paste
Unfortunately I seem to be missing something to translate between Inventor and Excel, but I don't know enough to even know if that's the issue.
Any advice is very much appreciated as I am still very new to VBA.
Ok. I had some code that I had copied off of a forum but didn't understand the functions going on. I believe this is what you are referring to "Application"?
wSheet2.Columns("G:G").select()
oExcelApp.Selection.cut()
wSheet2.Columns("B:B").Select()
oExcelApp.Selection.Insert(Microsoft.Office.Interop.Excel.XlDirection.xlToRight)
Although I don't understand what the
"(Microsoft.Office.Interop.Excel.XlDirection.xlToRight)" refers to. I understand the part about the direction and where it inserts just not whats before it.
I do agree with #DisGruntledDraftsman about not using Select and Activate. However, if you are just trying to get some working code that gets the job done, some simple tweaks can be done. Of course this isn't ideal but, it should work though.
row_Count = wSheet2.Range("B1048576").End(xlUp).Row
wSheet2.Activate
wSheet2.Range("B1").Select
Selection.AutoFill Destination:=wSheet2.Range("B1:B" & row_Count), Type:=xlFillDefault

Cutting a region on one worksheet and pasting to another doesn't work. But copy does. Why?

I have been struggling with this problem for awhile now.
I've written a VBA routine that is supposed to find a region on one worksheet, then cut and paste it to another worksheet. If I run the following code it doesn't work:
' This does not work
DSheet.Range(SummaryDataAddr, DSheet.Cells.SpecialCells(xlLastCell)).Cut
PSheet.Range(SummaryDataLocation).PasteSpecial Paste:=xlPasteValues
But if I change the code to copy the region from the first worksheet, paste it to the second worksheet, then go back to the first worksheet and explicitly delete the region, it works.
' But this does work. Why?
DSheet.Range(SummaryDataAddr, DSheet.Cells.SpecialCells(xlLastCell)).Copy
PSheet.Range(SummaryDataLocation).PasteSpecial Paste:=xlPasteValues
DSheet.Range(SummaryDataAddr, DSheet.Cells.SpecialCells(xlLastCell)).Delete
Has anyone seen this kind of problem before? Is there a way to use the cut function and get it all to work?
To access a the spreadsheet with the VBA code in it go here:
https://www.dropbox.com/s/satv6z95tlqw7lr/CutBug.xlsm?dl=0
The routine is called "CreateDLDataPivot" (it's a pared down version of a larger program I'm working on).
Thanks for any help!
PasteSpecial Paste:=xlPasteValues does not work with Range.Cut; it only works with Range.Copy.
Range.Cut only clears the cells, it does not delete the cells.
Try a direct value transfer and clear.
with DSheet.Range(SummaryDataAddr, DSheet.Cells.SpecialCells(xlLastCell))
PSheet.Range(SummaryDataLocation).resize(.rows.count, .columns.count) = .value
.clear 'use .clearcontents to retain formatting
end with

Update Bloomberg API static data

I want to copy and paste data from one sheet to another sheet. The original data is from Bloomberg API function. I found the Bloomberg data cell only updates after the macro finishes running. I tried to build a private function to let the static data update before I copy it. Here is my code:
Private Sub ProcesData()
Application.Run
Call Application.OnTime(Now + TimeValue("00:00:01"), "ProcessData")
End Sub
Sub Macro3()
Dim i As Integer
i = 1
Do Until i > 2
Sheets("Sheet1").Activate
Cells(1, 3).Value = Cells(i, 1)
i = i + 1
Call Application.OnTime(Now + TimeValue("00:00:01"), "ProcessData")
Range("C4:E181").Select
Selection.Copy
Sheets("Sheet2").Select
Range("A1").Select
lMaxRows = Cells(Rows.Count, "A").End(xlUp).Row
Range("A" & lMaxRows + 1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Loop
End Sub
Ah, Bloomberg API... many an issue.
So, when you do a Bloomberg request using a function call, the cell call site receives a call back and refreshes the data.
The problem is, w.r.t. automation, the data can come back in parts and you have to wait till it completes before continuing to process your data.
So, there are 3 approaches to this solution.
Last time I looked, this is the one that Bloomberg recommends. Have a routine that refreshes the call to the cell formula. This has a timer and recursively invokes itself until the data has been retrieved. The trick to this is to know when the data has been retrieved correctly. The data area is checked for errors which say it hasn't been completed yet.
The other solution is to invoke the call using Application.Run where you build the formula in code and invoke with VBA. This allows you to not deal with functions as such in the worksheet. But is effectively the same thing as 1.
You can set a reference to the Bloomberg API and use COM to do the request. This is a much cleaner approach and you can easier integrate this into your code effectively creating a Bloomberg data call API.
I would suggest, if possible going for option 3. Although a little more effort, te code becomes much cleaner. Options 1. and 2. can be tricky to debug when your workbooks become more complex in terms of structure etc.
If you search your Bloomberg help (the ever tremendous old 'F1 F1' help service should be able to point you in the right direction. Simply the most impressive help system ever done in my opinion!) Bloomberg does have some examples which demonstrate the methods highlighted above.
So, with the issue at hand and to finally answer your question :)
I would restructure your code to actually do function call that initially does a Calcuation (which will invoke your requests to Bloomberg). Then enter into a recursive function which calls itself until there are no errors in the data. After this you then copy your data.
Hope that helps.

Excel VBA Slow Calculation Loop Iterations

Not sure if this is a code-specific issue or not, so I will be general for now.
I have a somewhat complicated macro that begins by reading financial market data that is manually inputted by a user into a worksheet, and then proceeds to process that market data, generating the required market curves, etc., and then calculate the certain valuations of interest.
The process requires a lot of looping since there are thousands of instruments that need to be valued. However, I noticed that every now and then the macro will loop extremely slowly - on the order of about 2-3 seconds per iteration. When I have the Excel workbook up, I can see down at the bottom it is saying "Calcuating (4 Processors x% complete)".
To resolve the issue I have to manually force Excel to shut down; usually this fixes the problem and the next time I run the program it works fine.
I am running Windows 8 (not 8.1) and Excel 2013. I've heard that this combination is particularly prone to crashing/bugs (I've experienced this several times myself where Excel will take a very long time to process basic requests such as font formatting or will spontaneously crash for no apparent reason).
However, I'd like to ask the community to see if the problem is more universal/known.
Thanks!
As a general tip for creating fast excel macros: wherever prossible don't loop through cells, you will get much better performance using a with statement on a range object, or where you need to operate on the data in a more elaborate way try copying your range of data into a 2 dimensional array, looping through an array will be orders of magnitude faster than looping though cells in a worksheet, you can then dump the array back to the range.
Try application.visible = false in the beginning of your code. Then make sure to do application.visible = true at the end. Should help.
Try to change the cursor to xlBeam
It changes everything in terms of speed in Windows 8.1
Sub CurseurDefault(zz As Boolean)
If zz = True Then
Application.Cursor = xlDefault
'Call ShowCursor(True)
Else
Application.Cursor = xlIBeam
'Call ShowCursor(False)
End If
End Sub

Excel VBA That command cannot be used on multiple selections

I have got this code:
Worksheets("SOURCE_DATA_HIDDEN").Activate
Sheets("SOURCE_DATA_HIDDEN").Select
Columns("B").Copy
Sheets("RESOURCE_DEMAND").Select
Columns("C").Select
ActiveSheet.Paste
I use it to copy and paste a column from one sheet to another. The code used to work last time i checked and it somehow broke today.
It comes up with the following error:
Run time error 1004: That command cannot be used on multiple selections.
I really cant figure out what is going on. I haven't made any amendments to the code.
try to clear the clipboard Application.CutCopyMode = False
You can simplify that a lot more. If its just the values you are wanting too, change to PasteSpecial. Try this:
ThisWorkbook.Sheets("SOURCE_DATA_HIDDEN").Columns("B").Copy
ThisWorkbook.Sheets("RESOURCE_DEMAND").Range("C1").PasteSpecial Paste:=xlValues
Application.CutCopyMode = False
Eliminates all the selecting and activating, which is generally a habit you dont want to keep!

Resources