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.
Related
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.
Let's say I have two Excel Workbooks(in reality I have one sheet results and maybe a hundered other workbooks containing data). I would like to create a macro that allows me to take the arithmetic mean of a selection and paste that into my active cell. I have written a macro that allows me to paste copied values between different workbooks, really simple:
Sub PasteVal()
Selection.PasteSpecial xlPasteValues
End Sub
Trying to do the arithmetic mean copying does not work, however:
Sub PasteMean()
ActiveCell.PasteSpecial (Application.WorksheetFunction.Average(Selection))
End Sub
Any help would be appreciated
Thanks.
did you try ?
activecell.value=Application.WorksheetFunction.Average(Selection)
casually stumbled upon this post. consider the xlPasteSpecial method with
XlPasteSpecialOperation Enumeration.
xlPasteSpecialOperationAdd
xlPasteSpecialOperationDivide
xlPasteSpecialOperationMultiply
xlPasteSpecialOperationNone
xlPasteSpecialOperationSubtract
With Worksheets("Sheet1")
.Range("C1:C5").Copy
.Range("D1:D5").PasteSpecial _
Operation:=xlPasteSpecialOperationAdd
End With
I have been working on this project for a long time and am suddenly getting a new error whenever I close my Excel file. I get the error twice "The picture is too large and will be truncated." There is no picture in my file. I am pasting formats.
This seems to be one of the Excel "Unsolved Mysteries".
I am using MS Office Professional Plus 2010 on Windows 7.
I have researched this and tried the following:
Deleted all %temp% files
Ran CCleaner
Set CutCopyMode =
False after all paste special (formats)
Went to add/remove
programs and reconfigured Office to stop the Clip Organizer from
running. (Control Panel\Programs\Programs and Features -> MS Office
Professional Plus 2010 -> Change -> Add or Remove Features -> Office
Shared Features -> Clip Organizer -> Not Available, etc.)
Rebooted
None of that helped, so I narrowed down the source of the problem by commenting out function and subroutine calls, running the program, saving and then pressing "x" to close. I did this until I found the right sub. Then I commented out all the lines of the sub and added them back in one logical chunk at a time until I found the problem area. Here it is:
' *********** APPLY BASIC ROW FORMATTING FROM TEMPLATE ***********
' Copy basic row formatting from template and paste over all rows
wksTemplate.Rows(giHEADER_ROW + 1).Copy
myWS.Rows(lFirstRow & ":" & lLastRow).PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
The paste contains formatting only - colors, borders, number formats, wrapping etc. It probably pastes on a range of 200 rows on average.
I have not changed these 3 lines of code in months. Why now?
Has anyone solved this mystery?
Thanks,
Shari
I got this error after copying a range and then using a set of pastespecial calls:
.PasteSpecial xlPasteColumnWidths
.PasteSpecial xlPasteValuesAndNumberFormats
.PasteSpecial xlPasteFormats
solution was to copy an empty cell and pastespecial xlvalues back into itself:
' to avoid the message on closing the book - "picture is too large and will be truncated", copy and paste a singe empty cell
ThisWorkbook.Worksheets(1).Cells(1, 1).Copy
ThisWorkbook.Worksheets(1).Cells(1, 1).PasteSpecial xlValues
' clear clipboard
Application.CutCopyMode = False
I sometimes have the same problem as you, but i have many pictures in my files...
Also sometimes i have slow down (open/close or just standard calculations(menu popup...)).
Usually when i close the workbook, and reopen it, it works fine again.
I have maybe some answer, not sure if any help :
Do you use Global variables ?
for example, in module 1:
Option Explicit
Public BigObject as AnyBigSizeType
Sub xxx() 'code following
try to avoid using global variables, usually its a mess and not even usefull.
Also, just to be safe, try in the immediate window : activesheet.pictures.delete
(or even activesheet.shapes.delete , but this one also deletes comments and other stuff...)
I get the error when closing a file after a macro used the Range.Copy command, even if the clipboard is empty. Doing Application.CutCopyMode = False is not enough, but adding this at the end of macros that use the Range.Copy method seems to be the solution:
This is my solution:
'without this it will say "The image will be truncated because it's too large", because Excel is stupid
[A1].Copy
Application.CutCopyMode = False
I'm calling a third party remote call to get data.
after calling this function,datas will be filled from cells(1,1) to cells(10,1)
my code is like this
application.caculation = xlmanual
cells(1,1) = "some remotefunction"
application.calculate
while cells(10,1)<>"result"
wend
'if it goes here means we get the data
deal_with_data
however,my code would hang in the while loop.
so how to deal with this issue?
Your current approach of spinning in a while loop is not a good idea because it consumes all available resources to do...nothing. Or rather, it executes the comparison cells(10,1)<>"result" over and over as quickly as it can. And the user interface hangs in the meantime.
In short, you're finding that VBA does not lend itself well to asynchronous or multithreaded programming.
Thankfully Excel does give you a built in way to accomplish this, with a little effort: The Application.OnTime method. It lets you schedule a delayed call to method, keeping the UI (and any other VBA code) responsive and available in the meantime. You can use it to implement a sort of timer.
Here's the basic approach for your case. It checks the value of your test cell every 1 second. If the value has not changed, it schedules itself to check again in another second. If the value is "result" it calls another sub, where you would put the code to handle the results.
Public Sub CallRemoteFunc()
Application.Calculation = xlManual
Cells(1, 1) = "some remotefunction"
Application.Calculate
Call WaitForUpdate
End Sub
Public Sub WaitForUpdate()
If Cells(10, 1) <> "result" Then
Debug.Print "Still waiting"
Application.OnTime Now + TimeValue("00:00:01"), WaitForUpdate
Else
Call DoStuffWithData
End If
End Sub
While the vba code is running i do not expect any other cells to change unless you are doing something in the loop.
I would either use an if function and call this macro when you want to check the last cell. I can elaborate if you need.
Or, utilise the DoEvents vba function / method in the loop if you envisage the data changing while the loop is running. This function will enable, i believe, the application to still run and update the cells while this macro is running.
After some testing: I now suspect the DoEvents function will work the best for you.
I am trying to copy a column from one sheet to another. The code I am using is a recorded macro and it works fine until I connect it to a button. When I do so, it gives a
Run Time Error '1004': Select method of Range Class failed
Here is the code and I can see nothing wrong with it. When I hit debug it highlights the second line.
Sheets("Count").Select
Columns("C:C").Select
Selection.Copy
Sheets("Add Invintory").Select
Range("b1").Select
ActiveSheet.Paste
Sheets("Count").Select
Sheets("Count").Columns("A:A").Select
Columns("A:A").Select
Selection.Copy
Sheets("Add Invintory").Select
Range("A1").Select
ActiveSheet.Paste
I have no clue what the problem is. Please help
You should always avoid using .Select They are a major cause of errors. You may want to see How to avoid using Select in Excel VBA
Sub Sample()
Sheets("Count").Columns("C:C").Copy _
Sheets("Add Invintory").Columns("B:B")
Sheets("Count").Columns("A:A").Copy _
Sheets("Add Invintory").Columns("A:A")
End Sub
I think the issue is that you have written the code in another sheet's code module. If I'm in Sheet1, and write e.g.
Sheets("Sheet2").Select
Columns("A:A").Select
...then Excel assumes you are referring to the Columns on Sheet1 as it treats the current sheet as a default. Therefore, you've told Excel "select Sheet 2" then "select a column on Sheet 1"...which it can't do so it gives you an error message. The best solution would be not to use 'Select'...but you will still see in Siddharth's code that he has had to refer to sheet addresses explicitly
Your original code would have worked if placed in the ThisWorkbook module. Locations for entering code are explained towards the end of this Excel help video
When you are putting vba code into the "view sheet code" .. There definitely helps to use Application.Run ... to run macro..
I had problem i directly input macro to sheet code.. for selection in another sheet it claimed runtime error 1004.. So i created macro separately and then i put Application.Run my macro from sheet code.
Works out perfectly ;)
This Application.Run also helps when you have too big macro that excel claim it cant be so big. You can easily divide to several parts and then just run applications one by one.. ;)