I am a new user on Excel VBA, recently i encounter this error when ever i try to run my macro. What my macro do is by reading the cell row data and will create a chart by itself for export purpose, etc.
Below is my macro code
Sub CombinationChart()
Dim lastrow As String
Dim boundaryRow As String
ActiveSheet.Shapes.AddChart2(201, xlColumnClustered).Select
lastrow = mySheet.Range("A" & Rows.Count).End(xlUp).Row
boundaryRow = lastrow - 20
ActiveChart.SetSourceData Source:=Range("mySheet!$A$" & boundaryRow ":$B$" & lastrow) 'make sure the range is correct here
ActiveChart.FullSeriesCollection(1).ChartType = xlLine 'select which column should be the Line or the Column
ActiveChart.FullSeriesCollection(1).AxisGroup = 1
End Sub
The error part is here
ActiveChart.SetSourceData Source:=Range("mySheet!$A$" & boundaryRow ":$B$" & lastrow) 'make sure the range is correct here
My last row variable is the last row which contains data in the excel table whereas boundaryRow is a variable who gets the last row value and subtract it by 20 which is last row — 20 , but i just cant look for a way to put in my two variables into my ActiveChart.Range.
asked May 31, 2021 at 1:01
1
You have missed the concatenate operator (&
) in your problem line.
Here is how it should look:
ActiveChart.SetSourceData Source:=Range("mySheet!$A$" & boundaryRow & ":$B$" & lastrow)
&
was missing between boundaryRow
and ":$B$"
answered May 31, 2021 at 1:08
Samuel EversonSamuel Everson
2,0972 gold badges9 silver badges24 bronze badges
4
Here’s how to do what you want with a Range
object variable. I’m assuming here — since you use it to calculate lastRow
— that you have mySheet
defined as a Worksheet
object (probably globally).
Sub CombinationChart()
Dim lastrow As Long
Dim boundaryRow As Long
Dim chartData as Range
ActiveSheet.Shapes.AddChart2(201, xlColumnClustered).Select
lastrow = mySheet.Range("A" & Rows.Count).End(xlUp).Row 'mySheet is defined elsewhere
boundaryRow = lastrow - 20
Set chartData = mySheet.Cells(boundaryRow,1).Resize(21,2) ' 21 rows x 2 columns
ActiveChart.SetSourceData Source:=chartData 'make sure the range is correct here
ActiveChart.FullSeriesCollection(1).ChartType = xlLine 'select which column should be the Line or the Column
ActiveChart.FullSeriesCollection(1).AxisGroup = 1
End Sub
You could do this «on the fly» too, substituting in the expression I have assigned to chartData
to the SetSourceData
Source
parameter.
answered May 31, 2021 at 1:20
JoffanJoffan
1,4851 gold badge13 silver badges18 bronze badges
2
Weighted Average UDF
- Whatever you’re doing here, according to this link, that’s not how you calculate the weighted average (the last parameter seems redundant, dividing in the loop is wrong).
- The suggested
SUMPRODUCT/SUM
formula solution in the provided link will fail if there are cells not containing numeric values while the following function will ignore (skip) those cells.
Weighted Average
Option Explicit
Function WeightedAverage( _
ByVal ScoreColumnRange As Range, _
ByVal WeightColumnRange As Range) _
As Double
' Compare the number of rows and use the smaller number.
Dim rCount As Long: rCount = ScoreColumnRange.Rows.Count
Dim wrCount As Long: wrCount = WeightColumnRange.Rows.Count
If wrCount < rCount Then rCount = wrCount
' Create the references to the column ranges.
Dim srg As Range: Set srg = ScoreColumnRange.Cells(1).Resize(rCount)
Dim wrg As Range: Set wrg = WeightColumnRange.Cells(1).Resize(rCount)
' Write the values from the column ranges to arrays.
Dim sData As Variant, wData As Variant
If rCount = 1 Then
ReDim sData(1 To 1, 1 To 1): sData(1, 1) = srg.Value
ReDim wData(1 To 1, 1 To 1): wData(1, 1) = wrg.Value
Else
sData = srg.Value
wData = wrg.Value
End If
' Declare additional variables to be used in the For...Next loop.
Dim sVal As Variant, wVal As Variant ' Current Values
Dim r As Long ' Rows Counter
Dim tWeight As Double ' Total Weight
Dim tProduct As Double ' Total Sum
' Calculate the total weights and the total products.
For r = 1 To UBound(sData, 1)
sVal = sData(r, 1)
If IsNumeric(sVal) Then ' prevent invalid score
wVal = wData(r, 1)
If IsNumeric(wVal) Then ' prevent invalid weight
tWeight = tWeight + wVal
tProduct = tProduct + sVal * wVal
End If
End If
Next r
If tWeight = 0 Then Exit Function ' all were invalid
' Calculate and return the weighted average (the result).
WeightedAverage = tProduct / tWeight ' maybe you want to round?
End Function
Your Code Revised
Function WeightedAverage( _
ByVal DataColumnRange As Range, _
ByVal ValuesColumnRange As Range, _
ByVal TotalValue As Double) _
As Double
' Compare the number of rows and use the smaller number.
Dim rCount As Long: rCount = DataColumnRange.Rows.Count
Dim vrCount As Long: vrCount = ValuesColumnRange.Rows.Count
If vrCount < rCount Then rCount = vrCount
' Create the references to the column ranges.
Dim drg As Range: Set drg = DataColumnRange.Cells(1).Resize(rCount)
Dim vrg As Range: Set vrg = ValuesColumnRange.Cells(1).Resize(rCount)
' Write the values of the column ranges to arrays.
Dim dData As Variant, vData As Variant
If rCount = 1 Then
ReDim dData(1 To 1, 1 To 1): dData(1, 1) = drg.Value
ReDim vData(1 To 1, 1 To 1): vData(1, 1) = vrg.Value
Else
dData = drg.Value
vData = vrg.Value
End If
' Declare additional variables to be used in the For...Next loop.
Dim dVal As Variant, vVal As Variant ' Current Values
Dim r As Long ' Rows Counter
Dim tCount As Long ' Total Count
Dim Total As Double ' Total Value
' Calculate the Total? (there should be a math term for it)
For r = 1 To UBound(dData, 1)
dVal = dData(r, 1)
If IsNumeric(dVal) Then ' prevent invalid data
vVal = vData(r, 1)
If IsNumeric(vVal) Then ' prevent invalid value
tCount = tCount + 1
Total = Total + dVal * vVal / TotalValue
End If
End If
Next r
If tCount = 0 Then Exit Function ' all were invalid
' Calculate and return the weighted average (the result).
WeightedAverage = Total / tCount ' maybe you want to round?
End Function
- Remove From My Forums
-
Question
-
Hello,
Please, advise me where is the error in the following code:
Function Filter(Number As Integer, Name As String)
Select Case Name
Case «aaa»
Filter = True
Case «bbb»
Filter = True
Case Else
Select Case Number
Case 79001
Filter = True
Case Else
Filter = False
End Select
End Select
End FunctionThank you in advance!
-
Edited by
Friday, May 26, 2017 10:26 PM
-
Edited by
Answers
-
Function ABCDEFG(Number1 As Integer, Name1 As String)
….
Select Case Number1
Case 79001Hi Kate,
You can use nested Select Case statements, as you have already demonstrated in your example.
The problem lies in Case 79001. This value is too large for an Integer. You can better use the Long type..
You can further simplify your code:
Function ABCDEFG(Number1 As Long, Name1 As String) As Boolean Select Case Name1 Case "aaa", "bbb": ABCDEFG = True Case Else Select Case Number1 Case 79001: ABCDEFG = True End Select End Select End Function
as this function defaults False as result.
Imb.
-
Marked as answer by
KateStsv
Saturday, May 27, 2017 10:38 PM
-
Marked as answer by
-
ABCDEFG(20001;»gh»)
«Compile error: Expected list separator or )»
Hi Kate,
The arguments are to be separated by a comma:
boolean_result = ABCDEFG(20001,»gh»)
Imb.
-
Marked as answer by
KateStsv
Saturday, May 27, 2017 10:38 PM
-
Marked as answer by
The Expected: list separator or ) error message tells you that the compiler was expecting to find either a list separator (such as the comma that separates arguments in a function) or a closing parenthesis in the statement. In most cases, it highlights where the problem began. For example, the following statement, when compiled, generates an Expected: list separator or ) error message with the word World highlighted:
Answer = MsgBox(Hello World, vbInformation,»Test»)
The problem with the preceding line is that the words Hello World are supposed to be a string literal enclosed in quotation marks, but we forgot the quotation marks. The blank space between the words Hello and World has sent the compiler into a tizzy because it was expecting something else there. To correct the problem, put the quotation marks around the string literal:
Answer = MsgBox(«Hello World», vbInformation,»Test»)
With the quotation marks in place, the compiler can see that the entire string of text «Hello World» is the first argument, vblnformation is the second argument, and «Test» is the third argument.
Sometimes the Expected: list separator or ) error message points out a missing parenthesis in a statement. For example, the following statement generates such an error message when compiled:
PCase = «Mc» & UCase(Mid(PCase, 3, 1) & Mid(PCase, 4)
It’s rarely easy to see where a parenthesis needs to be added to a statement, especially if the statement contains lots of them. One fact is always true, though: Any statement that uses open parentheses must also use an equal number of closed parentheses.
Here’s a little trick that programmers use to see whether they have the right number of parentheses. You start with the number 0 in mind. Then you read from left to right. Each time you encounter an open parenthesis, add 1 to that 0. Each time you come to a closed parenthesis, subtract 1 from that number. By the time you get to the end of the line, you should be back to 0. If you end up at any other number, you have a problem.
As an example, Figure 12-7 shows the preceding troublesome line after counting open and closed parentheses. After you add 1 for each open parenthesis and subtract 1 for each closing parenthesis, you end up with 1. That number shows that you either have one too many open parentheses or you’re lacking one closed parenthesis.
Needless to say, you can’t just stick an extra closing parenthesis into the statement at random. Rather, you need to understand the syntax rules of the various functions used in the expression. The example in Figure 12-7 uses two functions named UCase() and Mid(). Each function needs its own, complete pair of parentheses.
Figure 12-7:
Counting open and closed parentheses in a statement.
0 +1 +1 -1 +1 -1 =1 II III Uh~°h
PCase — «Mc» & Ucase(Mid(PCase, 3, 1) & Mid(PCase, 4)_
The Mid(PCase, 4) function at the end of the statement is fine because the Mid() function requires exactly one open and one closed parenthesis. The larger Mid() function, Mid(PCase, 3, 1), is also okay because it has one open and one closed parenthesis.
The problem occurs with the UCase() function. That larger Mid(PCase, 3, 1) function is the argument for the UCase() function, and there’s no closing parenthesis for UCase(). That needs to be added right after the closing parenthesis for Mid(). Each of the Mid() functions also has a pair of open and closed parentheses. If you count the parentheses in the modified statement shown in Figure 12-8, the count ends up at 0, which is exactly what you want.
Figure 12-8:
Equal number of open and closed parentheses.
Regardless of which compile error message you get, you have to fix the problem before you can even run the procedure. Don’t expect the compile error message to pinpoint the solution for you. The message in a compile error is often too vague and too general for that. In most cases, your only recourse is to look up the correct syntax in Help (or through the Object Browser) and apply it to whatever you’re trying to accomplish.
Continue reading here: Checking on Variables with Debug Print
Was this article helpful?
У меня есть эта командная строка в VBA:
Call Shell("cmd.exe /S /k " & ""C:\Program Files\Java\jre1.8.0_171\bin\javaw.exe" -jar " & DPath & " """ & inp1 & """ """ & inp2 & """ """ & sPath & """ """ & FilePath & """", vbNormalFocus)
Когда я удаляю цитаты, в VBA появляется ошибка:
'C:\Program' is not recognized as an internal or external command, operable program or batch file.
Когда я добавляю цитаты, в VBA появляется ошибка:
Compile error: expected list separator or )
Как я могу решить ошибку?
3 ответа
Лучший ответ
Цитата неверна, вы должны поместить еще одну пару кавычек вокруг пути javaw.exe
, потому что в VBA литерал "
должен быть указан как ""
:
Call Shell("cmd.exe /S /K " & """C:\Program Files\Java\jre1.8.0_171\bin\javaw.exe"" -jar " & DPath & " """ & inp1 & """ """ & inp2 & """ """ & sPath & """ """ & FilePath & """", vbNormalFocus)
Но это все равно не сработает, потому что cmd
удаляет самые крайние кавычки и оставляет неверную командную строку. Поэтому вы должны предоставить еще одну пару (буквальных) кавычек вокруг всего выражения за /K
, которые могут быть удалены cmd
:
Call Shell("cmd.exe /S /K " & """""C:\Program Files\Java\jre1.8.0_171\bin\javaw.exe"" -jar " & DPath & " """ & inp1 & """ """ & inp2 & """ """ & sPath & """ """ & FilePath & """""", vbNormalFocus)
Наконец, позвольте мне порекомендовать заключить значение DPath
в кавычки (буквально):
Call Shell("cmd.exe /S /K " & """""C:\Program Files\Java\jre1.8.0_171\bin\javaw.exe"" -jar """ & DPath & """ """ & inp1 & """ """ & inp2 & """ """ & sPath & """ """ & FilePath & """""", vbNormalFocus)
0
aschipfl
15 Июл 2020 в 09:01
Call Shell("cmd.exe /S /k ""C:\Program Files\Java\jre1.8.0_171\bin\javaw.exe"" -jar " & _
DPath & " """ & inp1 & """ """ & inp2 & """ """ & sPath & """ """ & _
FilePath & """ ", vbNormalFocus)
… в зависимости от различных значений ваших объединенных переменных
-1
Tim Williams
15 Июл 2020 в 07:31
Пожалуйста, узнайте, как сделать вашу жизнь проще. То, что вы можете представлять «в строке VBA с помощью« », не означает, что вы должны это делать, за исключением самого тривиального случая.
Вот родной метод VBA для упрощения жизни.
Dim qDPath As String
Dim qinp1 As String
Dim qinp2 As String
Dim qsPath As String
Dim qFilePath As String
Dim qCommand As String
qDPath = MakeQuotedString(Path)
qinp1 = MakeQuotedString(inp1)
qinp2 = MakeQuotedString(inp2)
qsPath = MakeQuotedString(sPath)
qFilePath = MakeQuotedString(FilePath)
qCommand = MakeQuotedString("C:\Program Files\Java\jre1.8.0_171\bin\javaw.exe")
qCommand = MakeQuotedString("cmd.exe /S /k " & qCommand & "-Jar " & qDPath & qinp1 & qinp2 & qsPath & qFilePath)
Call Shell(qCommand, vbNormalFocus)
Несмотря на то, что вышеупомянутое намного более многословно, оно, по крайней мере, позволяет вам использовать один шаг через F8, чтобы на каждом этапе проверять, правильно ли вы строите последнюю командную строку.
Как вы можете видеть выше, это немного многословно, поэтому многие другие языки программирования имеют возможность вставлять переменные и маркеры форматирования в строку. Это также можно сделать в VBA, используя модуль, чтобы скрыть соответствующий код. Пожалуйста, посмотрите на метод Fmt в моем модуле макета для VBA. Его можно найти в GitHub здесь. Это очень простой библиотечный модуль, позволяющий встраивать переменные поля и маркеры форматирования в строки
Это позволит вам написать
Call Shell("cmd.exe /S /k " & ""C:\Program Files\Java\jre1.8.0_171\bin\javaw.exe" -jar " & DPath & " """ & inp1 & """ """ & inp2 & """ """ & sPath & """ """ & FilePath & """", vbNormalFocus)
В гораздо более сжатой форме, которая также дружелюбна для человеческого глаза.
Dim ShellCmd as String
ShellCmd = Fmt("cmd.exe /S /k {dq}{dq}C:\Program Files\Java\jre1.8.0_171\bin\javaw.exe{dq} -jar {dq}{0}{dq} {dq}{1}{dq} {dq}{2}{dq} {dq}{3}{dq} {dq}{4}{dq}{dq}", dpath, inp1, inp2, sPath, FilePath)
Call Shell(ShellCmd, vbNormalFocus)
Заранее извиняюсь, если мне все-таки не удалось получить {dq} несоответствие.
0
freeflow
15 Июл 2020 в 09:23