Scripting in Immediate Window [duplicate] - vba

This question already has an answer here:
Execute Multiple Lines in the Immediate Window of an Excel VBA workbook
(1 answer)
Closed 5 months ago.
is it possible to code short scripts in Immediate Window in VBA?
When I was using for example R or Python I had always open console in which I could easly check how short code is working (for example check the result of For loop if it returns range [a, b] or [a, b))
So for example: can I write
For i = 0 to 5
Debug.Print i
Next i
and run it without creating new module file/creating extra Sub?

You can put this in the immediate window:
For i = 0 to 5: Debug.Print i : Next i and press enter
It is not possible to have line breaks. But instead use a colon.

Related

Creating parallel multiple tasks with variable parameter [duplicate]

This question already has answers here:
Is there a reason for C#'s reuse of the variable in a foreach?
(4 answers)
Starting Tasks In foreach Loop Uses Value of Last Item [duplicate]
(2 answers)
Closed 5 years ago.
This is a cumbersome behaviour when creating several task in a for loop:
Private Sub DoSomeTasks()
For i = 1 to 3
Dim oTest as cTest = New cTest
Dim oTask As Task = Task.Factory.StartNew(Sub() oTest.DoSimulation(i))
Next
End Sub
This code will create all tasks with the same i value (= 3). Anyone has experienced something similar? Anyone has a clue on how to solve it?

Wend without While not working (no if/else/endif present) [duplicate]

This question already has answers here:
Break out of a While...Wend loop
(4 answers)
Closed 5 years ago.
I can't get the While/Wend loop to work at all. Even the tiniest possible case, such as below:
Sub TestingWhile()
Dim i As Integer
i = 0
Do While i < 10
i = i + 1
Wend
End Sub
The result of that code is an error message window saying "Compile error: Wend without While".
I found people having this error, but only because they always had some wrong if/else statements. This obviously is not the case. What's going on?
By the way, I'm using Microsoft Visual Basic for Applications 7.1 while in Excel 2013.
EDIT - Question solved. Syntax, beginner mistake: Do While is closed by Loop, and While is closed by Wend
Do While is closed by Loop and While is closed by Wend :
Sub TestingWhile()
Dim i As Integer
i = 0
Do While i < 10
i = i + 1
Loop
End Sub

Running a loop while debugging VBA

The Problem
I am trying to debug some code, and somewhere in the middle I stopped at a breakpoint. Now I want to change some variables and run a certain loop several times.
How far did I get?
I know how to change the variables, but somehow I get stuck when trying to run the loop in the immediate window. Here is an example:
Dim i As Integer
Dim j As Integer
For i = 0 To 6
j=i ' Do something
Next i
I tried several variations of the code, but each time I get the following error:
Compile error: Next without for
Other relevant information
I tried searching but mostly found information about problems with loops, whilst I am quite sure the loop itself is fine. (Especially as I reached it before arriving at the breakpoint).
The only place I saw someone addres this situation, he reduced the loop to a single line, however to do this every time would be very impractical in my case.
I realize that I could call a function containing the loop, and then the function call would probably work, but again this feels quite impractical. So I guess it boils down to the following question.
The question
What is a practical way to run a loop whilst debugging VBA code in Excel?
There is actually a way for using loops or other multi-line statements in the Immediate Window - using a colon : to separate statements instead of a new line.
Full solution is described here.
Note that in the Immediate Window you also don't have to declare the variables using a Dim statement.
To summarize, your snippet would look something like this:
For i = 0 To 6: j=i: debug.Print i+j: Next i
I think I understand your question. You want to run a multi-line code block (i.e. the loop) in the Immediate Window. This throws errors because the Immediate Window is only intended for single lines of code.
I don't have any suggestions other than those you already mentioned. I'd recommend putting your test loop into a separate function and calling that from the Immediate Window:
Sub Test()
Dim i As Integer
Dim j As Integer
For i = 0 To 6
j=i ' Do something
Next i
End
Another option is to set several breakpoints. You can also run one line of code at a time with F8.
What is likely the preferred method (i.e., what most people actually do) is use the full power of the IDE, which includes the Immediate, Locals and Watch panes. You can change the value of most variables at runtime by direct assignment in the Immediate Pane (i=6 will do exactly what you think it should do). The IDE also allows you to set breakpoints, add watch conditions, step through code line-by-line using the F8, step through function or procedure calls using Shift+F8, stepping over (and back) through code using the mouse/cursor, and with a few exceptions, you can even add new variables during runtime.

VBA Compile error

I have very little experience with VBA and the last time I used it was years ago.
Heres my VBA:
Function MacIDGen(total, current)
If total - current = 0 Then
current -1
Else
current 1
End If
Macro1 (current)
End Function
Sub Macro1(cur)
Sheets("Donations").Cells(I2).Value = cur & "Test"
End Sub
It's its own module, no other code in with it at all.
So I have a cell which is calling MacIDGen(). It's passing MacID two other cell values. The error comes whenever it's executed, "Compile Error: Expected Sub, Function, or Property" and highlights the functions method signature.
I have no idea why its kicking this up here, I'm guessing its because I've either missed a major step or something about how you can't have a function in that context or some other such issue.
EDIT
As a little extra info, I'm creating these spreadsheets in Excel to serve as random data generation sheets to be imported into a drupal site. I've encountered a problem that cannot be resolved without the use of loops (I also can't hard code the number of iterations either), which formulas don't do.
Regarding the Compile Error, you are getting that because you forgot to use the = sign in current -1 and current 1
Like I mentioned, there are many errors but the main error is that you cannot use a UDF to write to another cell. It really doesn't matter if you break that function into functions or subs. You simply can't write to any other cell. You will get a #Value in the cell where you are using that function.
A Function is used when you want to return something. Now since you are using this as a UDF (user defined function), it should return something and to that particular cell.
If you are writing to the same cell where the function is called from then change your code to
Function MacIDGen(total, current)
If total - current = 0 Then
current = -1
Else
current = 1
End If
MacIDGen = current & "Test"
End Function
If you want to change a cell you can use a sub procedure instead of a UDF, in that case you will need a way to execute it from your spreadsheet such as a commandButton, a ribbon button or a key combination shortcut.
If so, your first line should be:
Sub MacIDGen(total, current)

How delete a series from an Excel chart using VBA

I'm trying to delete the empty series from a chart in Excel 2003 using VBA. I've seen that others have had this issue in the past and I have tried all methods mentioned in their posts but have been unable to find anything that works consistently.
The chart has 14 series in it and anywhere between 3 or 9 of them can be empty. The empty ones are always between Series 4 - 12.
I've tried a few variations of code but this is primarily it:
Sheets("chart-1").Select
ActiveChart.PlotArea.Select
For i = 12 To 4 Step -1
Dim theSeries As Series
MsgBox (ActiveChart.SeriesCollection(i).Name)
Set theSeries = ActiveChart.SeriesCollection(i)
MsgBox (theSeries.Name)
theSeries.Delete
Next
I can run it successfully once for a chart, but all subsequent cycles fail with a Unable to get the Name property of the Series class error. It fails on the call to .Name.
I been able to get it work by inserting integers directly, but it will only run once for all integers except 1. It run it multiple times for Series(1).
For instance if I simply call: ActiveChart.SeriesCollection(1).Delete, then the series is deleted, but if I then run it with another integer (4, 9, 12) it won't run. It will work again for 1, but only 1. It will also work once with other integers (say 4), but all subsequent calls will fail even if I change the integer to 1 or keep it as 4, or change it to some other number.
The behaviour is really quite strange.
Any ideas would be greatly appreciated. I can't simply call ActiveChart.SeriesCollection(1).Delete repeatedly because the first 3 series are always non-empty.
Thanks.
** Update **
I just ran a test manually executing the following:
Sheets("ch-v2-12mth").Select
ActiveChart.PlotArea.Select
MsgBox (ActiveChart.SeriesCollection(1).Name)
I cycled through the SeriesCollection trying the numbers 1 - 16 (there are only 14 Series in the chart) to see the result.
1 - 3 worked fine
4 - 13 errored with Unable to get the Name property of the Series class
14 worked fine
15 - 16 errored with Method 'SeriesCollection' of object '_Chart' failed <- not surprising given the number of series in the chart.
This type of behaviour makes me think that there is a bug with Excel. Any other ideas?
There are bugs in Excel when you delete all the series from a chart. My workaround is to always leave at least one series (even if it has no data in it) in the chart. That seems to work for me.
Just thought of another thing. When you delete a series, the indexes of all the remaining series get reduced by one, so you can't delete them by looping from 1 to the number of series. What you can do instead is have a do loop that deletes them until the SeriesCollection.Count = 0 (or 1, see my comments earlier). Or a for loop that iterates backwards and always deletes the last series (i.e. SeriesCollection(SeriesCollection.Count).Delete
You cannot remove all series or the chart will remove itself. what I do to work around this is to rename all exisiting series; then enter your code to build new stuff; then run another snippet to remove the series you renamed
'rename existing series
With ActiveChart
DoEvents
For i = .FullSeriesCollection.Count To 1 Step -1
.FullSeriesCollection(i).Name = "remove" & i
Next i
End With
'your code here to build new charts
'last piece of code to remove the earlier series marked for deletion
With ActiveChart
DoEvents
For c = .SeriesCollection.Count To 1 Step -1
If .SeriesCollection(c).Name Like "*Series*" Then .SeriesCollection(c).Delete
Next c
End With
'also, you need to step backwards because each time you remove a series it will re-index
You can simplify your code to this:
Sheets("chart-1").Select
For i = 12 To 4 Step -1
MsgBox "Series " & i & ": """ ActiveChart.SeriesCollection(i).Name & """"
ActiveChart.SeriesCollection(i).Delete
Next
I don't know why the code was not working for you, but simpler is usually better. And you don't need to know the series name to delete a series.