Using SUMIF with ExecuteExcel4Macro - excel

I am trying to deal with some closed workbooks and tried to use ExecuteExcel4Macro approach and here's some hints
This is the normal formula
=SUMIF('[Example.xlsx]Sheet1'!$B:$B,C3,'[Example.xlsx]Sheet1'!$C:$C)
I used s string to store the address of column B and t to store the address of column t of the closed workbook
s = "'" & myDir & "[" & fn & "]" & "Sheet1" & "'!" & Columns(2).Address(True, True, -4150)
the same with the variable t but to change Columns(2) to Columns(3)
And in the immediate window I got something like that
'C:\Users\Any\Desktop\[Example.xlsx]Sheet1'!C2
Then I tried to use
Debug.Print ExecuteExcel4Macro("SUMIF(" & s & "," & Range("C3").Address(True, True, -4150) & "," & t & ")")
But I encountered an error Method ExecuteExcel4Macro of object _Global failed
Any ideas?
Another point how to get the worksheet name without the need to know the name by referring for example: Worksheets(1).Name in the variable s?
I noticed that the formula is working when the workbook is open but it throws an error #VALUE when the workbook is closed.

Related

How to resolve "expected end" error in vba?

I am trying to make this code work in vba excel however i keep receiving Expected End error
URL_Last = "&entry.7170534=" & EmpID & "&entry.634952910=" & EmpName & "&entry.1900852350=" & Gender & "&entry.776101390=" & Designation & "&entry.1211978069=" & Address & "&submit=Submit"
Form_URL = URL_First & URL_Last
May i ask what adjustment should i do inorder to fix this? Thanks

Product sum with dynamic sheet names in formula

We have a macro that loops through a set of 50 workbooks that have different amounts of sheets. The sheets look similar but all have different sheet names.
We want to place a formula in the first sheet ("Framsida") that searches through column B in sheet 3 to the last sheet to identify how many unique entries there are.
We have been working with PRODUCTSUM and FREQUENCY.
The formula works when pasted into the sheet manually.
When trying this with the macro, it starts linking to other data sources with the error message
"This workbook contains links to other data sources".
The code we tried:
Worksheets("Framsida").Range("m5").Formula = "=SUMPRODUCT(--(FREQUENCY(''" & Sheets(3).Name & " : " & Sheets(Sheets.Count).Name & " '!$B$6:$b$200, ' " & ActiveWorkbook.Sheets(3).Name & " : " & ActiveWorkbook.Sheets(Sheets.Count).Name & " '!$B$6:$b$200)<>0))"
This is the result that comes out in sheet "Framsida" when running the macro:
=PRODUKTSUMMA(--(FREKVENS('8007029 :[ 8007062 ] 8007062 '!$B$6:$B$200; '8007029 :[ 8007062 ] 8007062 '!$B$6:$B$200)<>0))
Where PRODUKTSUMMA=PRODUCTSUM
and FREKVENS=FREQUENCY
It adds the last sheet name in square brackets and we have no idea why. We are open for suggestions to other solutions.
This is the entire loop:
Sub SummeringFramsida()
'Variabler för loopen
Dim MyFile As String
Dim Filepath As String
'-----------------------------------------------------------------------------------'
'Öppnar filer tills det att man kommer till Huvudfilen i listan, filerna som ska sökas måste alltså ligga ovanför i listan'
Filepath = "C:\Users\JohannaFalkenstrand\Desktop\Excelfix\"
MyFile = Dir(Filepath)
Do While Len(MyFile) > 0
If MyFile = "Huvudfil.xlsm" Then
Exit Sub
End If
Workbooks.Open (Filepath & MyFile)
Workbooks(MyFile).Activate
Worksheets("Framsida").Range("m5").Formula = "=SUMPRODUCT(--(FREQUENCY('" & Sheets(3).Name & " : " & Sheets(Sheets.Count).Name & " '!$B$6:$b$200, ' " & ActiveWorkbook.Sheets(3).Name & " : " & ActiveWorkbook.Sheets(Sheets.Count).Name & " '!$B$6:$b$200)<>0))"
'Stänger, sparar och går till nästa fil'
Workbooks(MyFile).Save
Workbooks(MyFile).Close
MyFile = Dir
Loop
End Sub
Give it a try with Range(...).Address(1,1,xlA1,1). This will give you a string of range reference that contains both the workbook and the sheet reference. Then you can compile the required formula with simple string manipulation, like
For Each wb in <SomeCollectionOfWorkbooks>
For Each sh in wb.Sheets
Debug.Print "Copy this to the required cell = SUM(" & _
sh.Range("B6:B200").Address(1,1,xlA1,1) & ")"
Next
Next
The key is the external reference parameter of .Address.
It looks like you want to use same range but on different sheets at same time, so you need to check this out:
Create a reference to the same cell range on multiple
worksheets
Applying this to your code this should kind of work:
Worksheets("Framsida").Range("m5").Formula = "=SUMPRODUCT(--(FREQUENCY(" & Sheets(3).Name & ":" & Sheets(Sheets.Count).Name & "!$B$6:$b$200," & ActiveWorkbook.Sheets(3).Name & ":" & ActiveWorkbook.Sheets(Sheets.Count).Name & "!$B$6:$b$200)<>0))"

Variable Workbook Name in Formula

I am trying to write a code that takes a variable workbook name (declared earlier) and inputs it into a formula that will be pasted into a cell.
I have it to the point where the formula works if I just write the workbook in, and I have the variable declaration with the workbook path working okay, I just can't figure out the formatting to drop the variable into the formula code.
'''Spreadsheet opening and variable declaration
strFileToOpen = Application.GetOpenFilename _
(Title:="Select an updated Inventory Report", _
FileFilter:="Excel Files *.xls* (*.xls*),")
If strFileToOpen = False Then
'Displaying a message if file not choosedn in the above step
MsgBox "No file selected.", vbExclamation, "Sorry!"
'And existing from the procedure
Exit Sub
Else
End If
Workbooks.Open Filename:=strFileToOpen
Set InvRpt = ActiveWorkbook
InvRptName = ActiveWorkbook.FullName
Set InvSht = InvRpt.Worksheets("ALL")
'''Formula insert
ActiveCell.Formula = "=IF(ISERROR(GETPIVOTDATA(""Sec QTY Sum"", 'InvRptName'!$A$4,""Alias"",""" & y & """)),0,GETPIVOTDATA(""Sec QTY Sum"", 'InvRptName'!$A$4,""Alias"",""" & y & """))"
The end result would be for this code to work exactly like this, but with a variable instead of the workbook/sheet name:
ActiveCell.Formula = "=IF(ISERROR(GETPIVOTDATA(""Sec QTY Sum"", '[8-14-19 AM INVENTORY.xls]Sheet2'!$A$4,""Alias"",""" & y & """)),0,GETPIVOTDATA(""Sec QTY Sum"", '[8-14-19 AM INVENTORY.xls]Sheet2'!$A$4,""Alias"",""" & y & """))"
It always helps to place a Break Point into the line where you are having issues then use the Intermediate Window to figure out where it is going wrong. For example;
Place a Break Point at the last line where you have ActiveCell.Formula =
Run the code
In the Intermediate Window type ?"=IF(ISERROR(GETPIVOTDATA(""Sec QTY Sum"", 'InvRptName'!$A$4,""Alias"",""" & y & """)),0,GETPIVOTDATA(""Sec QTY Sum"", 'InvRptName'!$A$4,""Alias"",""" & y & """))"
Note; The ? instructs the Intermediate Window that you want to see a return value.
If it compiles ok you should see a resulting string, see if it looks as you expected. I'd guess your result will include the text 'InvRptName' where you are expecting '[8-14-19 AM INVENTORY.xls]Sheet2'.
To get '[8-14-19 AM INVENTORY.xls]Sheet2'!$A$4 try using;
?"'[" & ActiveWorkbook.Name & "]" & ActiveSheet.Name & "'!$A$4"
Another couple hot tips;
Use Debug.Print "add your messages here or a variable " & InvRptName within your code to output debug messages.
Use the Intermediate Widow to fix variables during execution InvRptName = "'[" & ActiveWorkbook.Name & "]" & ActiveSheet.Name & "'!$A$4" notice I excluded the ? this time.

Function for searching via vlookup in closed workbook is not working

I try to do a Vlookup in a closed workbook via ExecuteExcel4Macro. Since I need to find a lot of values in different workbooks it makes sense to do it in a closed workbook.
I used the below code, but it doesn't work if I enter the function on my Excel book:
=GetVlookup("D:", "testfile.xls", "Sheet1", "C1:D8", 2, "CDM-01_10")
I can assure that there is a file on my D: named testfile.xls with a sheet1 and content in the range I mention here. But result is #value!.
I want this in a function since I want to make a price calculation add-in that can be used in several workbooks, so I rather haven't introduced this in a macro.
Public Function GetVlookup(path, file, sheet, ref, Col, vVal)
' Retrieves a value from a closed workbook
Dim arg As String
' Make sure the file exists
If Right(path, 1) <> "\" Then path = path & "\"
If Dir(path & file) = "" Then
GetVlookup = "File Not Found"
Exit Function
End If
If IsNumeric(vVal) Then
vVal = CDbl(vVal)
Else
vVal = Chr(34) & vVal & Chr(34)
End If
' Create the argument
arg = "'" & path & "[" & file & "]" & sheet & "'!" & Range(ref).Address(, , xlR1C1)
' Execute an XLM macro
GetVlookup = ExecuteExcel4Macro("Vlookup(" & vVal & "," & arg & "," & Col & ",0)")
End Function

Excel VBA function to get value using variables from closed workbook

I have the following function which I use to fetch data from a closed workbook:
Public Function GetValue(path, file, sheet, ref)
' Retrieves a value from a closed workbook
Dim arg As String
' Make sure the file exists
If Right(path, 1) <> "\" Then path = path & "\"
If Dir(path & file) = "" Then
GetValue = "File Not Found"
Exit Function
End If
' Create the argument
arg = "'" & path & "[" & file & "]" & sheet & "'!" & _
Range(ref).Range("A1").Address(, , xlR1C1)
' Execute an XLM macro
GetValue = ExecuteExcel4Macro(arg)
End Function
Then I have the following test routine which works:
Sub TestGetValue()
p = Range("B2").Value
f = Range("B3").Value
s = "TOTAL"
a = "D" & ActiveCell.Row + 3
MsgBox GetValue(p, f, s, a)
End Sub
However, if I use the GetValue function in an Excel cell providing all 4 parameters exactly like in the routine, it always throws a #VALUE! error.
Why does it work in a routine and not while being called as a function?
After several attempts I did find 3 solutions:
Using a function with "ExecuteExcel4Macro"
Opening the other workbook in the background by vba procedure, then copy/pasting data
Creating external references by vba procedure, then leaving only values
First one while being able to use it as an excel custom formula, it is the slowest, especially when you need data from a specific range. So I don't recommend this option as it would slow your workbook down a lot.
Second option while being much faster, still takes around 15 seconds to get data from several ranges across 2 workbooks.
Third option was the fastest. Like an instant really less than 1 second execution time during which data was pulled from 2 closed workbooks and for different ranges.
Here's the 3rd option's procedure:
Sub getDS()
asname = "data"
bsname = "Anual"
csname = "Total"
filename = Sheets("data").Range("B64").Value
path = Sheets("data").Range("B63").Value
Dim ws As Worksheet
Set ws = Sheets("data")
With ws.Range("D4:D34")
.ClearContents
.Formula = "='" & path & "[" & filename & "]" & bsname & "'!R11"
.Value = .Value
End With
With ws.Range("J4:J34")
.ClearContents
.Formula = "='" & path & "[" & filename & "]" & bsname & "'!U11"
.Value = .Value
End With
With ws.Range("J37:J37")
.ClearContents
.Formula = "='" & path & "[" & filename & "]" & csname & "'!DW96"
.Value = .Value
End With
End Sub
I found this by far to be the BEST and FASTEST VBA solution to fetch data in an INSTANT from closed workbooks (with variables) without opening them.

Resources