Sub Process_Globals
'These global variables will be declared once when the application starts.
'These variables can be accessed from all modules.
Type DBResult (Tag As Object, **Columns As Map**, Rows As List)
Type DBCommand (Name As String, Parameters() As Object)
Private const rdcLink As String = "http://192.168.8.100:17178/rdc"
End Sub
This is the methods for process globals . Here columns As Map is initialized .
However the line bolded in the below code gives an error as , "Object converted to String. This is probably a programming mistake. (warning #7)"
Sub GetRecord
Dim req As DBRequestManager = CreateRequest
Dim cmd As DBCommand = CreateCommand("selectAllNames", Null)
Wait For (req.ExecuteQuery(cmd, 0, Null)) JobDone(j As HttpJob)
If j.Success Then
req.HandleJobAsync(j, "req")
Wait For (req) req_Result(res As DBResult)
'work with result
'req.PrintTable(res)
***Log(res.Columns)***
ListViewListTable.Clear
For Each row() As Object In res.Rows
Dim oBitMap As Bitmap
Dim buffer() As Byte
buffer = row(res.Columns.Get("gambar"))
oBitMap = req.BytesToImage(buffer)
ListViewListTable.AddTwoLinesAndBitmap(row(1), "See more...", oBitMap)
Next
Else
Log("ERROR: " & j.ErrorMessage)
End If
j.Release
End Sub
So what should I do to remove the error?
If columns is a map? (which it looks to be?).
Then to display the columns you can use this:
For Each MyKey As String in res.Columns.Keys
log("Key name = " & MyKey)
log("Key value = " & res.Columns.Get(MyKey))
Next
I'm a beginner in coding and am not familiar with "M" modeling language. I have an XML file that I want to use to load the data in Query Editor. In the Query, I need to expand only the table columns with a specific name below:
view
viewfolder
Attribute:name
I have found the following post where they give a function by Chris Webb for expanding all the lists(below code).
= (TableToExpand as table, optional ColumnNumber as number) =>
let
ActualColumnNumber = if (ColumnNumber=null) then 0 else ColumnNumber,
ColumnName = Table.ColumnNames(TableToExpand){ActualColumnNumber},
ColumnContents = Table.Column(TableToExpand, ColumnName),
ColumnsToExpand = List.Distinct(List.Combine(List.Transform(ColumnContents, each if _ is table then Table.ColumnNames(_) else {}))),
NewColumnNames = List.Transform(ColumnsToExpand, each ColumnName & "." & _),
CanExpandCurrentColumn = List.Count(ColumnsToExpand)>0,
ExpandedTable = if CanExpandCurrentColumn then Table.ExpandTableColumn(TableToExpand, ColumnName, ColumnsToExpand, NewColumnNames) else TableToExpand,
NextColumnNumber = if CanExpandCurrentColumn then ActualColumnNumber else ActualColumnNumber+1,
OutputTable = if NextColumnNumber>(Table.ColumnCount(ExpandedTable)-1) then ExpandedTable else ExpandAll(ExpandedTable, NextColumnNumber)
in
OutputTable
But how to expand only desired lists/tables?
You should be able to simply put a filter on the old ColumnsToExpand line.
That is,
TableColumns = //This is the old ColumnsToExpand definition renamed.
List.Distinct(List.Combine(List.Transform(ColumnContents, each if _ is table then Table.ColumnNames(_) else {}))),
ColumnsToExpand =
List.Select(TableColumns, each (_ = "view" or _ = "viewfolder" or _ = "Attribute:name")),
Or in one line like this,
ColumsToExpand = List.Select(List.Distinct(List.Combine(List.Transform(ColumnContents, each if _ is table then Table.ColumnNames(_) else {}))), each (_ = "view" or _ = "viewfolder" or _ = "Attribute:name")),
I am using Excel VBA. Does anyone know about a way to overcome the argument length limit of Application.Run()? (Or please suggest other function that can do the same job.)
Specific to my situation some of my constraints are:
I need to specify the called function as a string
The function is within a standard module
It is a function, the return value is needed, so Call() will not work.
In any case, I do not want the parameter list of the called function to be changed (e.g. to variant array or ParamArray) since I have written some other functionalities which depend on the function declaration.
EDIT: In response to some of the comments below I can provide a simplified version of my project here (could be off the original question though). In fact the whole design is established and running smooth except for the 30-arg constrain.
The very ultimate goal is to enable the following spreadsheet function which can be called like =mySpreadSheetFn("calledFn", "para1=abc", "para2=2002", ...). This will invoke the function calledFn() whose declaration may be:
Function calledFn(Optional para1 As String = "P1", _
Optional para2 As Integer = 202, _
Optional para3 As Boolean = True)
and the default argument will be replaced accordingly as specified in the ParamArray in the mySpreadSheetFn() call. Similarly there will be calledFn2() etc which an end user can use. So, there has to be an Application.Run() inside mySpreadSheetFn() .
And here are the function definitions:
Type paramInfo
Val As Variant
dataType As String 'can be Enum but let's forget it for this purpose
End Type
Function mySpreadSheetFunction(fnName As String, ParamArray otherParams())
Dim fnParams As Scripting.Dictionary
' getFnDefaultParams(fn): return the defaults and data types of fn's params
' as a Dictionary. Each item is of type paramInfo (see above)
Set fnParams = getFnParams(fnName)
' For each specified arg check whether it exists for the function.
' If so, replaces the default value with the input value.
' If not exist, then just ignore it
' The problem is really not with this part so just know
' we have all the parameters resolved after the for-loop
For i = LBound(otherParams) To UBound(otherParams)
Dim myKey As String
myKey = Split(otherParams(i), "=")(0)
If fnParams.Exists(myKey) Then
' parseParam() converts the input string into required data type
fnParams(myKey).Val = parseParam(Split(otherParams(i), "=", 2)(1), _
fnParams(myKey).DataType _
)
End If
Next
' Here is the issue since the call cannot go beyond 30 args
Dim lb As Integer: lb = LBound(fnParams)
Select Case UBound(fnParams) - LBound(fnParams) + 1
Case 1: Application.Run fnName, fnParams(lb).Val
Case 2: Application.Run fnName, fnParams(lb).Val, fnParams(lb + 1).Val
' Omitted, goes until Case 30
' What to do with Case 31??
End Select
' Some other operations for each call
End Function
' An example of function that can be called by the above mySpreadSheetFn()
Function calledFn(Optional para1 As String = "P1", _
Optional para2 As Integer = 202, _
Optional para3 As Boolean = True)
' needs to return value
calledFn = para1 & para2 * 1000
End Function
There is hardly any room to change the front-end since this is how the user interface is desired.
Any thoughts?
Probably a bit late, but if you transfer the method to a class, everything becomes much easier:
Class "c1"
Public Sub IHaveTooManyArguments(ParamArray params())
Debug.Print "Refactor me!"
End Sub
Module "Main"
Public Sub CallIHaveTooManyArguments(fnName As String, ParamArray params())
Dim o as new c1
CallByName o, fnName, VbMethod, params
End Sub
Pack several arguments into an array. Or pack several arguments into some sort of data document, like an Xml file/string, or a JSON file/string, or an ordinary text file.
If you're determined to call a procedure with more that 30 parameters via Application.Run, you'll need a trampoline procedure in order to match its function signature. Make a second prodecure that takes the parameters in an array (or some other package), and then pass that to a second procedure that calls the one with too many parameters:
Sub Test()
Dim args As Variant
args = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, _
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, _
31, 32)
Application.Run "ToManyArgsTrampoline", "fnName", args
End Sub
Sub ToManyArgsTrampoline(fnName As String, args() As Variant)
If UBound(args) = 31 Then
IHaveTooManyArguments fnName, args(0), args(1), args(2), args(3), args(4), args(5), _
args(6), args(7), args(8), args(9), args(10), args(11), _
args(12), args(13), args(14), args(15), args(16), args(17), _
args(18), args(19), args(20), args(21), args(22), args(23), _
args(24), args(25), args(26), args(27), args(28), args(29), _
args(30), args(31)
End If
End Sub
Sub IHaveTooManyArguments(fnName As String, ParamArray otherparams())
Debug.Print "Refactor me!"
End Sub
iam searching a way to check if a string is empty before converting it to date, problem i that i want to avoid if-else since i have to use it on multiple variable in single statement:
Call MyObj.Insert(CInt(Me.ddlFiltroPD), _
CInt(Me.Parent!ddlFiltroEsito), _
CInt(Nz(ddlFiltroPD.Column(1))), _
Nz(txtPuntoDebolezza, ""), _
CInt(Nz(Me.ddlRilevanza, 0)), _
Nz(txtInterventi, ""), _
Nz(txtOwner, ""), _
CDate(txtData1), _
CDate(txtData2), _
CDate(txtData3), _
CDate(txtData4), _
Nz(txtMotivazioneChiusura) _
)
txtData1, txtData2, txtData3 and txtData4 can be null and i have to convert it to a data when they are not null
i have thought to create a function to do the convertion or to use some temp variables but iam looking for something better
You can use this expression:
IIf(txtdata1 = vbNullString, "", CDate(txtdata1))
i solved in this way
Call MyObj.Insert(..., _
txtData1, _
txtData2, _
txtData3, _
txtData4, _
)
in MyObj.Insert i change parameter to variant and i transform parameter using Format(txtData1, "YYYYMMDD")
I continue to get a user-defined error. This code is very helpful in exporting data to access. It just won't kick off because of the User-defined error.
Thank you
Public Sub AccImport()
Dim acc As DAO.Database
acc.OpenCurrentDatabase "C:\Users\public\Database1.accdb"
acc.DoCmd.TransferSpreadsheet _
acImport, _
acSpreadsheetTypeExcel12Xml, _
"tblExcelImport", _
Application.ActiveWorkbook.FullName, _
True, _
"Folio_Data_original$A1:B10"
acc.CloseCurrentDatabase
acc.Quit
Set acc = Nothing
End Sub
You should tell us which line the error refers to, but it is most likely the second.
You need to add a reference to the DAO library. Go to Tools, References and find and tick Microsoft DAO 3.6 Object Library, so that you can then use DAO. in your code.
But OpenCurrentDatabase is an Access method. To use this, and then call TransferSpreadsheet, you need to use Access Automation. This involves:
Having a Reference to the Access Object Library
Creating a new instance of the Access Application, and having an
object variable that refers to this new instance
Then you can use OpenCurrentDatabase and TransferSpreadsheet.