I've been using StackOverflow for months and it has answered all of my questions, expect for the issue I'm currently having. I can't seem to fix the issue, no matter the options posted on this site. Maybe you can see the issue, that I'm not seeing at the moment.
I have one FormulaArray in VBA that takes the index of an external file, matches one value (Q2) with a value in column B of the external file. Then it matches a second value (P2) with a value in column D of the external file. If there's a match on both, it'll return a value that is in column C of the external file.
Works great in Excel, but the moment I create a Selection.FormulaArray = this formula, I get a 1004 in return. The line itself is shorter than 255 characters and even breaking up the INDEX and MATCH formulas into two parts (by Dim formulapart1 and formulapart2 as string) it doesn't work.
=INDEX([ISOCODE.xlsx]ISOCODE!$A:$D;MATCH(1;([ISOCODE.xlsx]ISOCODE!$B:$B=Q2)*([ISOCODE.xlsx]ISOCODE!$D:$D=P2);0);3)
I tried the following solution that was posted on this website that worked for others, but it's not working for me, no matter what I do:
Dim theFormulaPart1 As String
Dim theFormulaPart2 As String
theFormulaPart1 = "=INDEX([ISOCODE.xlsx]ISOCODE!$A:$D;XX"
theFormulaPart2 = "MATCH(1;([ISOCODE.xlsx]ISOCODE!$B:$B=Q2)*([ISOCODE.xlsx]ISOCODE!$D:$D=P2);0);3)"
With ActiveSheet.Range("DS2")
.FormulaArray = theFormulaPart1
.Replace "XX", theFormulaPart2
End With
There are issues with how you have split the code (your theFormulaPart1 is not a valid formula on its own!) but that's not the real issue here - that's your "XY Problem".
The real issue is that when putting a Formula in via VBA, unless you are using .FormulaLocal, you must use the English localisations - this means using , intead of ; to separate the arguments. And, there is no .FormulaArrayLocal, so for an Array formula you always use the English localisation:
ActiveSheet.Range("DS2").FormulaArray = "=INDEX([ISOCODE.xlsx]ISOCODE!$A:$D,MATCH(1,([ISOCODE.xlsx]ISOCODE!$B:$B=Q2)*([ISOCODE.xlsx]ISOCODE!$D:$D=P2),0),3)"
Whenever working with excel-VBA (or with anything in general), try always to start from something smaller, that works. In your case, remove the opend worksheet and try to make it work with the one you have. Thus, here is something that works:
Sub TestMe()
Dim theFormulaPart1 As String
Dim theFormulaPart2 As String
theFormulaPart1 = "=INDEX(A:D,XX"
theFormulaPart2 = "MATCH(1,(B:B=Q2)*(D:D=P2),0),3)"
With ActiveSheet.Range("E1")
theFormulaPart1 = Replace(theFormulaPart1, "XX", theFormulaPart2)
.FormulaArray = theFormulaPart1
End With
End Sub
Once you fix it, go further and include [ISOCODE!.xlsx]
Related
I've looked through all guides I can find on this subject but not a single one solves my problem.
I want to find the cell address of this vlookup function:
vlookadd = Application.Lookup(partno, Sheet3.Range("A5:B46"), 2, False)
(Currently dimmed as variant incase that needs to be changed)
I want to find the address of the value found and make it equal a variable so something like this:
batch1add = vlookadd.Address
The value found by the lookup function works fine but the address always comes up empty after trying lots of different possible solutions
as well as using find
cells(worksheetfunction.match(partno,range("a5:a46"),0)+4,2).address
The plus 4 is due to the start row of the range being 5, for example a match in row 5 will return 1.
Per the comments, using Find and an offset should be just fine.
Function getAddress(itemToFind As Variant, lookupRange As Range, columnOffset As Integer)
getAddress = lookupRange.Find(What:=itemToFind).Offset(0, columnOffset).address
End Function
Sub Example()
Dim batch1add As String
Set batch1add = getAddress(partno, Sheet3.Range("A5:B46"), 2)
End Sub
As PEH advised in the prior answer's comments: Incorporating some error handling would be wise, as both implementations assume the value exists whenever they're called.
I'm having a hard time figuring out what's wrong with this snippet of code which should be elemental. I was wondering if someone could give me a hand. Any ideas would be very much appreciated, I'm pretty new in VBA.
My code is:
Dim table() as Variant: table = Array(Array(0,0,0))
Dim aux() as Variant: aux = Array(0,0,0)
If table(0) = aux then
End If
The code doesn't even execute, Excel throws a mismatch exception in the If line. I have "paraphrased" the code in every way possible and haven't been successful on getting it to work (of course the code is not as simple as this one, but this one that does nothing doesn't execute either...)
Thanks in advance for your time,
If you want to compare two 1-dimensional arrays for equality as indicated by your provided sample code, then you'll need to use the Join function, like so:
Sub tst()
Dim table() As Variant: table = Array(Array(0, 0, 0))
Dim aux() As Variant: aux = Array(0, 0, 0)
If Join(table(0), ",") = Join(aux, ",") Then
MsgBox "The same"
Else
MsgBox "Not the same"
End If
End Sub
As a note, make sure the Join delimiter being used will not be in any of the elements of either array being tested against. John Coleman brought up a great point that this could give a false positive against an array of (0, "0,0") when using a comma delimiter as shown in the provided answer.
I have reduced my problem to the following code example. I am using a German Excel version in which separators in normal Excel formulas are semicolons ";" instead of "," (e.g. =SUMME(A1;A3) instead of =SUM(A1,A3)).
Now the code which works different from time to time:
Sub CommasDoNotWorkAnymore()
Dim a()
Dim i%
a = Array("A1,A3,A5", "B1", "B2")
i = 0
Debug.Print Sheets(1).Range(a(i)).Address
End Sub
Normally, when starting Excel, this code works. But sometimes Excel seem to switch the accepted separators used in the Range() to semicolons untill I restart Excel. This occurs most times when rerunning the code after a runtime error.
Is this a general Excel bug? Does anybody know what is behind this behaviour? Is there some Excel-wide "local option" for the Range class?
EDIT: I just tried to convert the a(i) with CStr(a(i) but this does also not work. So no ByRef kind of problem...
If you want to control it, check first what separator is currently in use. What I guess is that you want to know the list separator:
Application.International(xlListSeparator)
Check other separators here:
https://msdn.microsoft.com/en-us/vba/excel-vba/articles/application-international-property-excel
The other time I had a problem with identifying decimal separator in VBA. Finnally I was able to get it in this way:
Function GetVBAdecimalSep()
Dim a(0) As Variant
a(0) = 1 / 2
GetVBAdecimalSep = Mid(a(0), 2, 1)
End Function
Changing separator not always works. Please see this: Changing decimal separator in VBA (not only in Excel)
The best solution is to check/change locale, even temporary.
Application.LanguageSettings.LanguageID(msoLanguageIDUI)
gives the LCID which would be 1033 for English (US)
In Excel VBA how can I set cell validation so that it works in all locales?
This code works in my locale, semicolon separated
Dim mySheet As Worksheet
Set mySheet = ThisWorkbook.Worksheets("Sheet 1")
Dim myRange As Range
Dim validValues as String
validValues = "a;b;c"
Set myRange = mySheet.Cells(2, 2)
myRange.Validation.Add _
Type:=xlValidateList, _
AlertStyle:=xlValidAlertStop, _
Formula1:=validValues
But I've seen that other locales needs comma separated
validValues = "a,b,c"
Essentially what I need is this, but I don't know how to determine 'id' in way that works in all locales.
' Internationalized delimiter
Dim id as String
id = ???
validValues = "a" & id & "b" & id & "c"
Edit:
There seems to be a "semicolon mode" of Excel that I do not understand and which I cannot reproduce reliably. I had a certain instance of Excel that got into this mode and all code run inside it worked with semicolon and not comma. I wrote a project in this instance and it worked, I would have thought I just made a mistake if not for all the code that I now have to rewrite...
Any hints in order to figure this out is appreciated.
Edit2:
After restarting Excel it changed it's mode to comma, I've been using it for a while but now this problem hit me again, Excel started using ';' (semicolon) instead of ',' (comma) as delimiter for my data validations.
This time I took a screenshot. Data validation is set to List.
Source is set to:
zero,one,both
This is the result, as you can see Excel does not care about my commas and displays all on the same line:
With source set like this it works:
zero;one;both
Result:
It is a mystery to me why Excel does this but I really need to find a way to make sure this never happens to my customer. Any help appreciated!
I have just dealed with a similar problem. I couldn't find a reason for why this happens, so I don't have a solution for good. Yet, I found a way around the problem that could be of use.
The only thing that you would need is to assign a valid value to the validated range before adding the validation.
After running your code, if the .Formula1 argument worked with semicolons, then there is no problem at all. If it didn't, the .Validation.Value property of the range returns False and you can use that as a trigger to rerun your code, replacing the semicolon separated list by a comma separated one. Then just rerun the validation.
For example:
myRange.value = "a" 'Assuming "a" is a valid value contained in the validvalues string
If myRange.Validation.Value = False Then
validvalues = replace(validvalues,";",",")
myRange.validation.modify Formula1:= validvalues
End if
Then you can clear the range value if you do not wish to have a default value shown.
I believe you are looking for a delimiter that would work on multiple scenarios (please let me know if this is not your query).
comma, semicolon, are sometimes good delimiter but often they pose serious syntax and some other string related errors .
Triple question mark ??? is also not a good choice in this case.
I prefer to go with | (the pipe) in these situations.
Sorry for the long answer :)
Microsoft says you need to use commas in VBA
https://support.microsoft.com/en-us/help/299490/data-validation-list-entries-all-on-one-line-in-excel
I am trying to reduce the time taken to generate the reports for an application. We generate the reports in Excel. We found that some calculation are much faster in Excel using formula than programmatically doing it in VB.net
So basically I need to use the following formula(Time difference) in VB.net code. but it is giving me an error.
=IF(F2>E2, F2-E2, ("24:00:00"-E2)+F2)
What I tried
Dim f As String = "=if(RC[-1]>RC[-2], RC[-1]-RC[-2], (" & "24:00:00" & "-RC[-2])+RC[-1]"
wbXl.Sheets("time diff", 7).FormulaR1C1 = f
wbXl.Sheets("time diff").Cells(2, 7).FormulaR1C1 = """"=if(RC[-1]>RC[-2], RC[-1]-RC[-2], ("24:00:00" & "-RC[-2])+RC[-1]""""
and few other combination but nothing seems to be working.
Any pointers or help would be really helpful.
Where do I start…
Dim f As String = "=if(RC[-1]>RC[-2], RC[-1]-RC[-2], (" & "24:00:00" & "-RC[-2])+RC[-1]"
That is not a valid syntax in Excel (you can’t assign the value at the time you Dim it… get .net if you want to do that!)
What is up with the “24:00:00” in quotes? Why not just subtract 1?
And all the quotes… it should be:
Cells(2, 7).FormulaR1C1 = "=if(RC[-1]>RC[-2], RC[-1]-RC[-2], (""24:00:00""-RC[-2])+RC[-1])"
Or better:
Cells(2, 7).FormulaR1C1 = "=if(RC[-1]>RC[-2], RC[-1]-RC[-2], (1-RC[-2])+RC[-1])"
I’m also assuming you're using RC notation because you're going to do dynamic entry. Otherwise, just use the cell IDs (easier to maintain). Re-reading, it’s in .net calling Excel (what I’m gathering). Otherwise, I’d say the sheet syntax should be different. (and most people prefer Range to Cell. Cell(2,7) is harder to read than Range("$G$2"). )
And here’s how I’d write the formula:
=B8+(B8<A8)-A8
(or in RC: =RC[-1]+(RC[-1]<RC[-2])-RC[-2])
Removes some of the redundancy of the original:
=IF(B6>A6,B6-A6,("24:00:00"-A6)+B6)