how to write query with function inside it in access vba? - excel

Lets suppose, vba code has
Dim SQL as String
SQL ="select * from table"
I found function that helps to combine values from related rows into a single concatenated string value.But when i implemented to my code it didn't work because double quotation inside query creating errors.What could be best format to make syntax valid in vba.The function is given below and link is (Combine values from related rows into a single concatenated string value).
SELECT
i.N_ID,
i.F_Name,
i.L_Name,
ConcatRelated(
"Course_ID",
"tbl_Courses",
"N_ID = '" & [N_ID] & "'"
) AS Course_IDs
FROM tbl_Instructors AS i;

Most likely, your ID is numeric, not text, thus no single-quotes:
SELECT
i.N_ID,
i.F_Name,
i.L_Name,
ConcatRelated(
"Course_ID",
"tbl_Courses",
"N_ID = " & [N_ID] & ""
) AS Course_IDs
FROM tbl_Instructors AS i;

Related

Automatically Run Access Query w/ date range parameters

Trying to automatically run an access query in excel and update the date criteria based on user input. Not sure how to code in vba a parameter for entering the between date and getting the query to post automatically in excel under a header column in a2.
Access Query:
'''SELECT hosp_chg.HOSP_ACCT_ID, hosp_chg.SVC_DATE, hosp_chg.POST_DATE, [hosp_chg.POST_DATE]-
[hosp_chg.SVC_DATE] AS [Lag Days], hosp_chg.ACCT_CLASS_ID, acct_class_master.TITLE, "" AS
[Inpatient or Outpatient], hosp_chg.REVENUE_CODE_ID, hosp_chg.COST_CENTER_ID,
cost_center_master.COST_CENTER_CODE, cost_center_master.COST_CENTER_NAME, "" AS [WDY Cost
Center Mapping], hosp_chg.DEPT_ID, department_master.DEPT_NAME, hosp_chg.PROC_ID,
procedure_master.PROC_CODE, procedure_master.PROC_NAME, hosp_chg.ORIG_AMT, hosp_chg.QUANTITY,
hosp_chg.LATE_CHG_YN, user_master.USER_ID, user_master.USER_NAME,
user_master.DEFAULT_USERROLE, "" AS [Include/Exclude in Reporting],
hosp_chg.REVERSE_ORIG_TRAN_ID, hosp_chg.REPOST_ORIG_TRAN_ID,
hosp_chg.LATE_CHG_CRED_ORIG_TRAN_ID, hosp_chg.LATE_CHG_CORRECT_ORIG_TRAN_ID
FROM acct_class_master INNER JOIN ((((hosp_chg INNER JOIN cost_center_master ON
hosp_chg.COST_CENTER_ID = cost_center_master.COST_CENTER_ID) INNER JOIN department_master ON
hosp_chg.DEPT_ID = department_master.DEPT_ID) INNER JOIN procedure_master ON hosp_chg.PROC_ID
= procedure_master.PROC_ID) INNER JOIN user_master ON hosp_chg.USER_ID = user_master.USER_ID)
ON acct_class_master.ID = hosp_chg.ACCT_CLASS_ID
GROUP BY hosp_chg.HOSP_ACCT_ID, hosp_chg.SVC_DATE, hosp_chg.POST_DATE, [hosp_chg.POST_DATE]-
[hosp_chg.SVC_DATE], hosp_chg.ACCT_CLASS_ID, acct_class_master.TITLE,
hosp_chg.REVENUE_CODE_ID, hosp_chg.COST_CENTER_ID, cost_center_master.COST_CENTER_CODE,
cost_center_master.COST_CENTER_NAME, hosp_chg.DEPT_ID, department_master.DEPT_NAME,
hosp_chg.PROC_ID, procedure_master.PROC_CODE, procedure_master.PROC_NAME, hosp_chg.ORIG_AMT,
hosp_chg.QUANTITY, hosp_chg.LATE_CHG_YN, user_master.USER_ID, user_master.USER_NAME,
user_master.DEFAULT_USERROLE, "", hosp_chg.REVERSE_ORIG_TRAN_ID, hosp_chg.REPOST_ORIG_TRAN_ID,
hosp_chg.LATE_CHG_CRED_ORIG_TRAN_ID, hosp_chg.LATE_CHG_CORRECT_ORIG_TRAN_ID, ""
HAVING (((hosp_chg.POST_DATE) Between [Enter the beginning date MM/DD/YY] And [Enter the
ending date MM/DD/YY]) AND ((hosp_chg.ORIG_AMT)>0) AND ((hosp_chg.LATE_CHG_YN)="Y") AND
((hosp_chg.REVERSE_ORIG_TRAN_ID) Is Null) AND ((hosp_chg.REPOST_ORIG_TRAN_ID) Is Null) AND
((hosp_chg.LATE_CHG_CRED_ORIG_TRAN_ID) Is Null) AND ((hosp_chg.LATE_CHG_CORRECT_ORIG_TRAN_ID)
Is Null))
ORDER BY hosp_chg.REVENUE_CODE_ID;'''
'
My error is on the parameters but i do not know how to fix any help would be greatly appreciated. THANKS IN ADVANCE!!
Ricardo A has given you a good answer. Here's the VBA code to do what he suggests:
Have the user enter the beginning and ending dates in two cells of the workbook, perhaps cells X1 and Y1
Use the data from those cells to put the values in the query as follows (assuming your query is a variable named SQL):
SQL = Replace(SQL, "[Enter the beginning date MM/DD/YY]", "#" & range("X1").text & "#")
SQL = Replace(SQL, "[Enter the ending date MM/DD/YY]", "#" & range("Y1").text & "#")
That will put the values into your query as date literals.

How do I change a Parameter in Power Query without it converting the value to a formula?

I was following the instructions on this thread:
How to Change Excel Power Query Paramaters with VBA
which lists the following code for changing a Power Query parameter:
ThisWorkbook.Queries([ParameterName]).Formula = 'New code here
However it converts the value into a formula and adds "= " to the front of it:
I need to update the source of my query because the GUID expires and needs to be refreshed.
Source = Xml.Tables(Web.Contents("http://api.aceproject.com/?fct=getprojects&guid=" & GUID & "&Filtercompletedproject=False&projecttemplate=0&assignedonly=True")),
The only solutions I can find require using a value stored in a cell, but I want to avoid storing the GUID in a cell for security reasons.
Using VBA how can I change either just the parameter value (without it converting into a formula) or the entire source URL?
The solution was using double quotes to force a text value to the formula:
ThisWorkbook.Queries("GUID").Formula = """dogs"""
Here's the final version, which passes the variable through as text:
Sub RefreshQuery_Click()
ThisWorkbook.Queries("GUID").Formula = """" & GUID & """"
End Sub
To ensure the query retains the parameter property, add in the following meta data:
ThisWorkbook.Queries("GUID").Formula = """" & GUID & """" & " meta [IsParameterQuery=true, Type=""Text"", IsParameterQueryRequired=true]"

SQLClient Command Parameter Query String Length

I am connecting to a SQL Server and am trying to limit the results by adding parameters. The first parameter I added, #sdate, worked just fine. But, now I am trying to add a second parameter which is not working. I want the field, LP_EOC_DATA.PL, to only be returned if the length of the string is greater than 6 characters long. The code below executed, and like I say, the dates returned were correct, but it also returned values from LP_EOC_DATA.PL that had string lengths less than 6. Please let me know if you know how to get this to work. Thanks in advance.
Sub doSQL()
Dim myConn As SqlConnection
Dim myCmd As SqlCommand
Dim myReader As SqlDataReader
Dim sqlString As String = "SELECT LP_EOC_DATA.PL as PLs, LP_EOC_DATA.cDate as ReadDate, LP_EOC_LOV.LOCATION as Location " &
"FROM LP_EOC_DATA INNER JOIN LP_EOC_LOV ON LP_EOC_DATA.PIC = LP_EOC_LOV.PIC " &
"WHERE LP_EOC_DATA.cDate > (#sdate) AND LEN(LP_EOC_DATA.PL) > #slen1 " &
"UNION SELECT dbo.VT_DATA.PL as PLs, dbo.VT_DATA.cDate as ReadDate, dbo.VT_LOV.LOCATION as Location " &
"FROM dbo.VT_DATA INNER JOIN dbo.VT_LOV ON dbo.VT_DATA.PIC = dbo.VT_LOV.PIC " &
"WHERE dbo.VT_DATA.cDate > (#sdate) AND LEN(dbo.VT_DATA.PL) > #slen1 " &
"ORDER BY ReadDate;"
myConn = New SqlConnection("SERVER=ServerName;UID=uName;" &
"PWD=Password;")
myCmd = myConn.CreateCommand
myCmd.CommandText = sqlString
myCmd.Parameters.AddWithValue("#sdate", DateTimePicker1.Value)
myCmd.Parameters.AddWithValue("#slen1", 6)
'myCmd.Parameters.AddWithValue("#rx1", "'%[^0-9a-z]%'")
'myCmd.Parameters.AddWithValue("#rx2", " dbo.VT_DATA.PL NOT LIKE '%[^0-9a-z]%'")
myConn.Open()
myReader = myCmd.ExecuteReader()
Table.Load(myReader)
DataGridView1.Visible = True
DataGridView1.DataSource = Table
lblTotal.Text = Table.Rows.Count
End Sub
Also, as you can see, I am looking to add another parameter that only returns alphanumeric results from the same LP_EOC_DATA.PL field. I haven't got quite that far yet, but if you see something I'm doing wrong there too, I'd appreciate the input.
It helps if you format your SQL a little more. There's some structure, but it still comes off as a big wall of text. It's even harder for us to debug than it is for you, since we don't know your schema at all. There are also a number of other little things you should do different before we even address the question (Using block so connection is closed in case of exception, avoid AddWithValue() for index safety, isolate SQL from user interface, etc):
Function doSQL(StartDate As DateTime) As DataTable
Dim result As New DataTable
Dim sqlString As String = _
"SELECT LP_EOC_DATA.PL as PLs, LP_EOC_DATA.cDate as LPRReadDate, LP_EOC_LOV.LOCATION as Location " &
"FROM LP_EOC_DATA " &
"INNER JOIN LP_EOC_LOV ON LP_EOC_DATA.PIC = LP_EOC_LOV.PIC " &
"WHERE LP_EOC_DATA.cDate > #sdate AND LEN(COALESCE(LP_EOC_DATA.PL,'')) > #slen1 " &
"UNION " &
"SELECT dbo.VT_DATA.PL as PLs, dbo.VT_DATA.cDate as ReadDate, dbo.VT_LOV.LOCATION as LPRLocation " &
"FROM dbo.VT_DATA " &
"INNER JOIN dbo.VT_LOV ON dbo.VT_DATA.PIC = dbo.VT_LOV.PIC " &
"WHERE dbo.VT_DATA.cDate > #sdate AND LEN(COALESCE(dbo.VT_DATA.PL,'')) > #slen1 " &
"ORDER BY ReadDate;"
Using myConn As New SqlConnection("SERVER=ServerName;UID=uName;" &
"PWD=Password;"), _
myCmd As New SqlCommand(sqlString, myConn)
myCmd.Parameters.Add("#sdate", SqlDbType.DateTime).Value = StarDate
myCmd.Parameters.Add("#slen1", SqlDbType.Int).Value = 6
myConn.Open()
result.Load(myCmd.ExecuteReader())
End Using
Return result
End Function
And then call it like this:
Dim tbl As DataTable = doSql(DateTimePicker1.Value)
DataGridView1.Visible = True
DataGridView1.DataSource = tbl
lblTotal.Text = tbl.Rows.Count
As for the question, there are a few possibilities: NULL values can give unexpected results in this kind of situation (the code I posted already accounts for that). You may also have trouble with certain unicode whitespace padding your character count. Another possibility is char or nchar fields instead of varchar or nvarchar, though I don't think that's the issue here.
This is not an answer to the question per se but a reply to the request for an XML literal example. As that requires a few lines of code, I'd rather not put it in a comment.
Dim sql = <sql>
SELECT *
FROM MyTable
WHERE MyColumn = #MyColumn
</sql>
Dim command As New SqlCommand(sql.Value, connection)
Note that the element name can be anything you want but I usually use 'sql' when it's for SQL code.

Passing string result to query then export as csv

Good Afternoon,
I have an access query that contains a list of all my customers lets call that CUS
I have another query that has a list of ORDERS
I would like to write some VBS that cycles through the customer list and exports a csv file containing all orders that belong to that customer.
The vba would then move on to the next customer on the list and perform the same action.
Any help would be great.
Snippet of code below
almost there cant get the WHERE condition working it keeps displaying a popup for me to populate however the same string is feeding the msgbox fine here is a snippet below tht is within the loop
strcustcode = rs!OCUSTCODE
ordercount = rs!orders
TIMEFILE = Format$(Time, "HHMM")
MsgBox ([strcustcode] & " has " & [ordercount] & " orders")
StrSQL = "Select * From [24-ND_Cus] where [24-ND_Cus].[OCUSTCODE] = strcustcode "
Set qd = db.CreateQueryDef("tmpExport", StrSQL)
DoCmd.TransferText acExportDelim, , "tmpExport", "c:file.csv" db.QueryDefs.Delete "tmpExport" –
Don't use [ ] around VBA variables. Don't use parens for the MsgBox when you just want to give user a message. The parens make it a function that requires a response by user to set a variable.
MsgBox strcustcode & " has " & ordercount & " orders"
Concatenate the variable into the SQL statement. If OCUSTCODE is a text type field, use apostrophe delimiters for the parameter.
StrSQL = "Select * From [24-ND_Cus] Where [OCUSTCODE] = '" & strcustcode & "'"
I don't advise code that routinely modifies design and changing a query SQL statement is changing design. If the only change is filter criteria and a dynamic parameterized query won't work, I suggest a 'temp' table - table is permanent, data is temporary. Delete and write records to the table and export the table.

How to Split a String and Store in MS Access table

I would like to be able to split a string of text that has been entered into a textbox on a MS Access form and store the split strings as separate records under the same field. This is the code I have so far, but I keep running into problems at every corner. I'm fairly new to this, but have been learning quickly. Any help is appreciated.
Here is what I'd like to accomplish: If I enter the following text into a text box ("this is a sentence") and click submit. I would like each other the words to be stored as individual records under a common field. Seems simple, but it's causing quite a few headaches.
Private Sub Submit_Click()
Dim SetDBConnection As ADODB.Connection
Set SetDBConnection = CurrentProject.Connection
Dim strInsertRecord As String
Dim strNewPhrase As String
Dim strStorePhrase As String
strNewPhrase = textPhrase
strStorePhrase = Split(NewPhrase)
strInsertRecord = "INSERT INTO [FieldSplice] (words) VALUES (" & strStorePhrase & ")"
SetDBConnection.Execute strInsertRecord
textPhrase.Value = Null
End Sub
I'm a little unclear on why you have the ADODB connection... is this connecting to an external database? If so, that makes sense, but then you are missing some code to get the insert to work properly.
If this is just an internal (native) Access table, then I don't think you need any of that. Here is a simple example of how you would take a string, split it into words (based on a space) and then insert those into your table:
Dim textPhrase As String
Dim words() As String
Dim i As Integer
textPhrase = "This is a test"
words = Split(textPhrase, " ")
sql = "parameters P1 text; INSERT INTO [FieldSplice] (words) VALUES ([P1])"
Set query = CurrentDb.CreateQueryDef("FsInsert", sql)
For i = LBound(words) To UBound(words)
query.Parameters("P1").Value = words(i)
query.Execute
Next i
CurrentDb.QueryDefs.Delete ("FsInsert")
One other note of interest -- you don't need to declare the insert each time. You can set a parameter, assign values to the parameter and execute the insert command multiple times. This is included in my example above.
Your code was trying to say:
insert into [table] (field) values ("value1", "value2", "value3")
Which you can't do. That has to be done as three inserts, unless your database supports array inserts (Oracle, for example).
The multiple fields only works like this:
insert into [table] (field1, field2) values ("value1", "value2")
Where each value corresponds to a column in the table.

Resources