Syntax error when passing variable args in macro - vba

I have a macro for libreoffice that takes in 2 arguments.
A file path
Variable args that are sheet names to look for.
I iterate over the document pertaining to the first arg and get the sheet that matches the first variable arg. I then convert that sheet to CSV.
Sub ExportToCsv(URL as String, ParamArray sheetNames() As Variant)
Dim saveParams(1) as New com.sun.star.beans.PropertyValue
saveParams(0).Name = "FilterName"
saveParams(0).Value = "Text - txt - csv (StarCalc)"
saveParams(1).Name = "FilterOptions"
saveParams(1).Value = "44,34,0,1,1" ' 44=comma, 34=double-quote
GlobalScope.BasicLibraries.loadLibrary("Tools")
URL = ConvertToURL(URL)
document = StarDesktop.loadComponentFromUrl(URL, "_blank", 0, Array())
baseName = Tools.Strings.GetFileNameWithoutExtension(document.GetURL(), "/")
directory = Tools.Strings.DirectoryNameoutofPath(document.GetURL(), "/")
sheets = document.Sheets
sheetCount = sheets.Count
Dim x as Integer
Dim requiredSheetIndex as Integer
For x = 0 to sheetCount -1
sheet = sheets.getByIndex(x)
sheet.isVisible = True
For i = LBound(sheetNames) To UBound(sheetNames)
If StrComp(sheet.Name, sheetNames(i), vbTextCompare) = 0 Then
requiredSheetIndex = x
End If
Next
Next
currentSheet = document.GetCurrentController.GetActiveSheet()
sheet = sheets(requiredSheetIndex)
document.GetCurrentController.SetActiveSheet(sheet)
filename = directory + "/" + baseName + ".csv"
fileURL = convertToURL(Filename)
document.StoreToURL(fileURL, saveParams())
document.close(True)
End Sub
Eg. ExportToCsv(<path>, 'Data'). Suppose the document has 4 sheets with the 3rd sheet as DATA, this sheet should be converted to CSV.
Previously I used to give the sheet idnex directly into the macro and it worked perfectly. But requirements changed and I have to pass in an array of possible names to match on. Hence the variable args.
But now I am getting a syntax error(Screenshot attached). I cant figure out what is wrong here.

I believe it is complaining about the ParamArray keyword. After a little digging, I discovered you need to include:
option compatible
at the top of your module. For more information, you can refer to this link.

Related

LibreOffice Calc: Can I get the cell address from VLOOKUP?

I'm using VLOOKUP, in Calc, like this:
VLOOKUP(B11,G2:J7,4,0)
Normally when any of us uses this, we want to get the value in the cell this function finds. In this case, rather than the value, I'd like to get a string with the cell address in it instead or the row and column of that cell. For instance, if I have a double precision floating point value of 30.14 in cell J5 and that's the answer, rather than having it return 30.14, I want it to return something like "J5" or 9,4 or some other way for me to read the result in a macro.
I've tried using =ADDRESS() and =CELL("address", ) but I'm getting errors (=CELL() gives me '#REF!').
EDIT: I'm using this routine as a wrapper around VLOOKUP with a table of floating point numbers (which is why it returns a DOUBLE instead of getting the cell value as a STRING or something else). All I have to do is pass it the column I want to get the data from:
Function getLookup(valColumn as Integer) as Double
oDoc = ThisComponent
oSheet = oDoc.Sheets (workSheet)
rangeInfo = lookupTopLeft + ":" + lookupBottomRight
cellRange = oSheet.getCellRangeByName(rangeInfo)
oCell = oSheet.GetCellByPosition(dataCellColumn, dataCellRow)
searchValue = oCell.getString()
Mode = 0
svc = createUnoService( "com.sun.star.sheet.FunctionAccess" )
args = Array(searchValue, cellRange, valColumn, Mode)
getLookup = svc.callFunction("VLOOKUP", args)
End Function
Note I'm using some local variables in this. They're private, for the module only, so I don't have to change cell references in multiple places while I'm working on designing my spreadsheet. "lookupTopLeft" and "lookupBottomRight" are "G2" and "J7", the top left and bottom right cells for the data I'm working with. "dataCellColumn", and "dataCellRow" are the column and row coordinates for the source for the key I'm using in VLOOKUP.
(#JohnSUN, I think this may be modified from an answer you provided somewhere.)
I'd like to be able to do a similar wrapper routine that would return the column and row of a cell instead of the value in the cell.
One of many possible options:
Option Explicit
Const lookupTopLeft = "G2"
Const lookupBottomRight = "J7"
Const dataCellColumn = 1
Const dataCellRow = 10
Const workSheet = 0
Function getCellByLookup(valColumn As Integer) As Variant
Dim oSheet As Variant, cellRange As Variant, oCell As Variant
Dim oColumnToSearch As Variant
Dim oSearchDescriptor As Variant
Dim searchValue As String
Dim nRow As Long
oSheet = ThisComponent.getSheets().getByIndex(workSheet)
cellRange = oSheet.getCellRangeByName(lookupTopLeft + ":" + lookupBottomRight)
searchValue = oSheet.GetCellByPosition(dataCellColumn, dataCellRow).getString()
Rem If we are looking not for a value, but for a cell,
Rem then using VLOOKUP is unnecessary, a simple Find is enough
oColumnToSearch = cellRange.getCellRangeByPosition(0, 0, 0, _
cellRange.getRows().getCount()-1) ' Resize full range to one first column
Rem Set search params
oSearchDescriptor = oColumnToSearch.createSearchDescriptor()
oSearchDescriptor.setSearchString(searchValue)
oSearchDescriptor.SearchType = 1 ' Search in Values!
Rem Try to find searchValue in oColumnToSearch
oCell = oColumnToSearch.findFirst(oSearchDescriptor)
If Not IsNull(oCell) Then ' Only if the value was found
nRow = oCell.getRangeAddress().StartRow
Rem Offset oCell to valColumn
oCell = cellRange.getColumns().getByIndex(valColumn-1).GetCellByPosition(0,nRow)
getCellByLookup = Replace(oCell.AbsoluteName, "$", "")
Else ' If the value from B11 is not found - warn about it
getCellByLookup = "Not found"
EndIf
End Function

Concatenated string is not recognized by my Sub

I made the following Sub to help me copy values from other workbooks or even just from other sheets within the same workbook.
Private Sub CopyValues(fromSheet As String, fromRange As String, toSheet As String, toRange As String, Optional fromFileName As String = "")
Dim toFile As Excel.Workbook
Set toFile = ActiveWorkbook
Dim fromFile As Excel.Workbook
If Len(fromFileName) > 0 Then
Set fromFile = Workbooks.Open(fromFileName)
Else
Set fromFile = ActiveWorkbook
End If
With ActiveWorkbook
toFile.Sheets(toSheet).Range(toRange).Value = fromFile.Sheets(fromSheet).Range(fromRange).Value
End With
If Len(fromFileName) > 0 Then
fromFile.Close savechanges:=False
End If
End Sub
It works pretty well (and you all are free to use it if you find it helpful). Below is an example of code that works:
Call CopyValues(reportName, "B4:C15", reportName, "E2:F13", reportDirPath)
Unfortunately, I'm having trouble with a specific case. I'm looking to copy the same value into multiple cells in the same column. Below is what I came up with:
For i = 2 To i = 13
Call CopyValues(reportName, "AJ2", reportName, "H" + i, reportDirPath)
Next i
That didn't work. No error messages, but none of the values were pasted into my sheet. I thought that maybe concatenating the integer i was converting (is that the technical word?) the string to a different type, so I tried the following:
For i = 2 To i = 13
Call CopyValues(reportName, "AJ2", reportName, CStr("H" + i), reportDirPath)
Next i
That still didn't work. Same deal. No error messages, but none of the values were pasted into my sheet.
Changing the + to an & also didn't work:
For i = 2 To i = 13
Call CopyValues(reportName, "AJ2", reportName, CStr("H" & i), reportDirPath)
Next i
Obviously, I could just write out each individual case, but that seems kind of ridiculous. Any idea what's going on?
When I tried your code your 'For' loops were not working, but after I changed your for loop to say 'For i = 2 to 13' as opposed to 'For i=2 To i = 13' the last version of your code worked for me.
For i = 2 To 13
Call CopyValues("Sheet1", "A1", "Sheet2", CStr("J" & i))
Next i
End Sub
So I think that could have been your trouble.

Excel VBA user defined function to find images in folder (match excel names to folder names of images)

Currently i am using a function to match image names from excel sheet to image folder, but i want one more thing... that if i save image and forget to add its name in excel then it should show me that i forget to add name.
for example if i save 3 images in image folder
16095_1.jpg,16095_2.jpg,16095_3.jpg
and i add image names in excel sheet as
16095_1.jpg,16095_2.jpg
then it should warn me that i forget one image name in excel cell.
my image name format is - 16095_1.jpg,16095_2.jpg
function i am using is...
Function findimage(Path As String, ImageList As String)
Dim results
Dim x As Long
Dim dc 'double comma
results = Split(ImageList, ",")
If Not Right(Path, 1) = "\" Then Path = Path & "\"
For x = 0 To UBound(results)
results(x) = Len(Dir(Path & results(x))) > 0
Next
dc = InStr(ImageList, ",,")
If dc = 0 Then
findimage = Join(results, ",")
Else
findimage = ("Double_comma")
End If
End Function
This function takes a folder path and a variable number of patterns (See MSDN - Parameter Arrays (Visual Basic)). Using the MSDN - Dir Function to iterates over the file names in the folder path and compares them against the patterns with the MSDN - Like Operator (Visual Basic) to count the number of files that match the patterns.
Usage:
getFileCount("C:\Users\Owner\Pictures",".gif",".png")
getFileCount("C:\Users\Owner\Pictures","*.gif"
getFileCount("C:\Users\Owner\Pictures","apple_.gif","banana_.gif", "orange_##.*")
getFileCount("C:\Users\Owner\Pictures","#####_#.gif")
Function getFileCount(DirPath As String, ParamArray Patterns() As Variant) As Integer
Dim MyFile As String
Dim count As Integer, x As Long
If Not Right(DirPath, 1) = "\" Then DirPath = DirPath & "\"
MyFile = Dir(DirPath, vbDirectory)
Do While MyFile <> ""
For x = 0 To UBound(Patterns)
If MyFile Like Patterns(x) Then
count = count + 1
Exit For
End If
Next
MyFile = Dir()
Loop
getFileCount = count
End Function

Runtime error 9: Subscript out of range - Pulling data from another worksheet

I'm writing a macro that pulls data from one workbook and places it into another. I think I have the code pretty much right except for an error I'm getting in one of my loops:
"Runtime error 9: Subscript out of range"
Here is the code:
Sub PullFromRunsheetsTest2()
Application.EnableEvents = False
Application.ScreenUpdating = False
Dim file As Variant, a As String, columnItertor As Integer, path As String
path = "C:\Users\msala\Desktop\Runsheets\"
file = Dir(path & "Runsheet*")
Do Until file = "" ''looking at the first file and loops until the last one
columnIterator = 0 ''setting this as the first set of 8 numbers - will shift the next set of numbers down 8 so they don't overwrite themselves
rowIterator = 0
Do Until rowIterator = 7
a = Workbooks(file).Worksheets("Pacman Runsheet").Cells(7, (2 + rowIterator)).Value '' Set "a" = whatever value is in B7, and iterate through that row
''^^^^(THIS IS WHERE I'M GETTING THE ERROR)
ActiveSheet.Cells(5 + rowIterator + columnIterator * 8, 1).Value = a ''take that value and put it in this column, iterate through.
rowIterator = rowIterator + 1
Loop
columnIterator = columnIterator + 1 ''(ignore this for now)
file = Dir()
Loop
End Sub
From what I've read it seems like there's some sort of problem with maybe the data type of a? Not entirely sure what that might be though. Am I accidentally declaring a as an array somewhere?

deactivate the current sheet before going to another sheet

I am getting error while swapping with two sheets.
I open one sheet and paste some data in this,after that I call a function which opens another sheet.but when I again paste data in the first sheet it throws error.
For y = 1 To size
Set src = Workbooks.Open("C:Template\Mapping.xlsx")
Worksheets("Sheet1").Activate
Worksheets("Sheet1").Range("B" & rowCntr).Value = "abc"
newValue= getNewValue()
rowCntr=rowCntr+1
Next
public Function getNewValue()
Dim newV=123
Set src = Workbooks.Open("C:Template\Mapping - Development v1.0.xlsx")
getNewValue=newV
End Function
For the first time it works properly but after calling the function getNewValue() it throws error "Subscript out of range" at Worksheets("Sheet1").Range("B" & rowCntr).Value = "abc" line.
Please help.
Your code example is incomplete. Noteably, it doesn't define what src is, but that is exactly what the error is: I must assume that srcis a global variable and you set src in both your main function and in function getNewValue.
When getNewValue returns, src now points to another workbook in which your ranges don't exist.
Further I am not sure whether opening the workbook again and again results in it being reloaded, reset or that multiple copies will be opened. I suggest you open them only once, e.g.:
Dim src as Object
Dim src2 As Object
Function main (size As Integer)
Dim y As Integer
Dim rowCntr As Integer
Set src = Workbooks.Open("C:Template\Mapping.xlsx")
Set src2 = Workbooks.Open("C:Template\Mapping - Development v1.0.xlsx")
For y = 1 To size
src.Worksheets("Sheet1").Activate
src.Worksheets("Sheet1").Range("B" & rowCntr).Value = "abc"
newValue= getNewValue()
rowCntr=rowCntr+1
Next
End Function
Public Function getNewValue()
Dim newV
newV = 123
'...whatever you want to do...
getNewValue = newV
End Function
no need for selection/activation, use objects (workbook, range) reference instead, like follows
Set src = Workbooks.Open("C:Template\Mapping.xlsx") '<~~ open workbook outside the loop since it doesn't depend on it
For y = 1 To size
src.Worksheets("Sheet1").Range("B" & rowCntr).Value = "abc" '<~~ use "src" workbook reference to point to it whatever may be the currently active workbook
newValue= getNewValue()
rowCntr=rowCntr+1
Next