Copying and Modyfing the Connection with VBA - vba

I'm currently building a solution using VBA to copy my existing query (API query) and change its parameters depending on the values in columns from the original query.
I'm using the p1 variable that contains a looped column values to be used in API URL
The result should be a multiple sheets with one query each, vba code should loop through a certain column in my first query and then pass this values into each new query.
I encountered a problem. I don't know if its regional formatting issue or not, but i cannot really paste the query into Queries.Add method. I was pretty sure i formatted the "" correctly but:
AS you can see editor flashed this part of code in red (in Notepadd++ with VBA formatting its fine)
Here is my code:
mFormula =
"let" & Chr(13) & "" & Chr(10) & " Source = Json.Document(Web.Contents(""https://rejestr.io/api/v1/krs/"" & p1 & ""/relations"", [Headers=[Authorization=""xxxxxxx""]]))," & Chr(13) & "" & Chr(10) &" #""Converted to Table"" = Table.FromList(Source, Splitter.SplitByNothing(), null, null, ExtraValues.Error), " & Chr(13) & "" & Chr(10) & " #""Expanded Column1"" = Table.ExpandRecordColumn(#""Con" & _
"verted to Table"", ""Column1"", {""address"", ""business_insert_date"", ""ceo"", ""current_relations_count"", ""data_fetched_at"", ""first_entry_date"", ""historical_relations_count"", ""id"", ""is_opp"", ""is_removed"", ""krs"", ""last_entry_date"", ""last_entry_no"", ""last_state_entry_date"", ""last_state_entry_no"", ""legal_form"", ""name"", ""name_short"", ""nip"", ""regon"", ""type"", ""w_likwidacji"", ""w_upadlo" & _
"sci"", ""w_zawieszeniu"", ""relations"", ""birthday"", ""first_name"", ""krs_person_id"", ""last_name"", ""organizations_count"", ""second_names"", ""sex""}, {""Column1.address"", ""Column1.business_insert_date"", ""Column1.ceo"", ""Column1.current_relations_count"", ""Column1.data_fetched_at"", ""Column1.first_entry_date"", ""Column1.historical_relations_count"", ""Column1.id"", ""Column1.is_opp"", ""Column1.is_rem" & _
"oved"", ""Column1.krs"", ""Column1.last_entry_date"", ""Column1.last_entry_no"", ""Column1.last_state_entry_date"", ""Column1.last_state_entry_no"", ""Column1.legal_form"", ""Column1.name"", ""Column1.name_short"", ""Column1.nip"", ""Column1.regon"", ""Column1.type"", ""Column1.w_likwidacji"", ""Column1.w_upadlosci"", ""Column1.w_zawieszeniu"", ""Column1.relations"", ""Column1.birthday"", ""Column1.first_name"", ""Column1.krs_person_id"", ""Column1.last_name"", ""Column1.organizations_count"", ""Column1.second_names"", ""Column1.sex""})" & Chr(13) & "" & Chr(10) & "in" & Chr(13) & "" & Chr(10) & " #""Renamed Columns3"""
Also, is it entirely possible to dynamically pass multiple variables from first query to create multiple queries to API service? Maybe someone already did something similar?
Many thanks
Alex

You need a line continuation marker (_) in the mFormula = line:
mFormula = _

Related

dynamic search box filters using LIKE

I have a dynamic search box filtering a subform based on user input. I also have a few filter buttons that filter the same subform. I set up the search box to incorporate preexisting filters applied by those buttons.
All that works fine. The problem I have is:
The dynamic filter using the LIKE statement only seems to work correctly when the length of the filter text is >= 3. Go below that and it applies some wonky filtering. Maybe I am using the statement wrong. I thought it would look if the field's value contains the search string somewhere in it. But it seemingly accepts values like "Natronlauge 50% techn. EN 896" for a search string of "Hä", which seems weird to me. It works once I add a third character though. Lines 11 and 13:
Me.Form.Filter = "[bezeichnung] LIKE '*" & SearchBoxStoffe & "*' AND [kategorie] = '" & Forms![HUB]![FilterAlleLink] & "'"
Would be nice if someone has some ideas how to go about these issues.
Here the full code for my searchbox:
Private Sub SearchBoxStoffe_KeyUp(KeyCode As Integer, Shift As Integer)
On Error GoTo errHandler
Dim filterText As String
'Apply dynamic filter for current filter category.
If Len(SearchBoxStoffe.Text) > 0 Then
filterText = SearchBoxStoffe.Text
If Forms![HUB]![FilterAlleLink] = "" Then
Me.Form.Filter = "[bezeichnung] LIKE '*" & SearchBoxStoffe & "*'"
Else
Me.Form.Filter = "[bezeichnung] LIKE '*" & SearchBoxStoffe & "*' AND [kategorie] = '" & Forms![HUB]![FilterAlleLink] & "'"
End If
Me.FilterOn = True
'Retain filter text in search box after refreshing.
SearchBoxStoffe.Text = filterText
SearchBoxStoffe.SelStart = Len(SearchBoxStoffe.Text)
Else
'Revert to current main filter category.
If Forms![HUB]![FilterAlleLink] <> "" Then
Call FilterStoffe("[kategorie] = '" & Forms![HUB]![FilterAlleLink] & "'")
Else
If Forms![HUB]![FilterAlleLink] = "" Then
Me.Filter = ""
Me.FilterOn = False
End If
End If
End If
'Set focus back to search box
SearchBoxStoffe.SetFocus
Exit Sub
errHandler:
MsgBox Err.Number & " - " & Err.Description, vbOKOnly, "Error ..."
End Sub
The dynamic filter using the LIKE statement only seems to work
correctly when the length of the filter text is >= 3. Go below that
and it applies some wonky filtering.
I don't really know why this is happening, but try the below. It makes use of the Change() event and covers 4 scenarios:
Both filters applicable.
Search Box only.
Main category only.
Nothing (clear the filter).
Also, I don't know what the FilterStoffe() method does, but I assume it just applies the main filter only.
Private Sub SearchBoxStoffe_Change()
On Error GoTo Trap
Select Case True
'both filters
Case Len(SearchBoxStoffe.Text) > 0 And Not IsNull(Forms.HUB.FilterAlleLink.Value):
Form.Filter = "[bezeichnung] LIKE '*" & SearchBoxStoffe.Text & "*' AND [kategorie] = '" & Forms.HUB.FilterAlleLink.Value & "'"
FilterOn = True
'SearchBox only
Case Len(SearchBoxStoffe.Text) > 0:
Form.Filter = "[bezeichnung] LIKE '*" & SearchBoxStoffe.Text & "*'"
FilterOn = True
'FilterAlleLink only
Case Not IsNull(Forms.HUB.FilterAlleLink.Value):
Form.Filter = "[kategorie] = '" & Forms.HUB.FilterAlleLink.Value & "'"
FilterOn = True
'Nothing
Case Else:
FilterOn = False
Filter = vbNullString
End Select
Leave:
On Error Resume Next
SearchBoxStoffe.SetFocus
Exit Sub
Trap:
MsgBox Err.Number & " - " & Err.Description, vbOKOnly, "Error ..."
Resume Leave
End Sub
Keep in mind, within the Change() event, the Text property gets updated with every keystroke and when the control loses the focus, it gets copied to the Value property.
However, the Value is the default property when you just reference the control.
So this
Me.SearchBoxStoffe
is the same as this:
Me.SearchBoxStoffe.Value
There were 2 issues that prevented the searchbox from running as intended:
Object references in the project were created with 2 different language versions of access. Objects would call other objects using the formulation of one language, which in turn called objects using referencing in another language etc. In cases where fields and/or queries would return empty, this would cause some of the references to no longer function as intended. The result was the program running out of stack space, empty controls on subforms that returned empty queries, objects not being found and more.
The searchbox filter was lagging behind the text in the searchbox by one event. If entering a new search string, the applied filter would always be missing the last character when using SearchBoxStoffe in the filter statement. Entering "Wood" would cause the filter to apply "Woo" etc.
The solutions are the following:
Fix all the references in the file manually to either language version and do not mix them up going forward.
The Value of the search box SearchBoxStoffe is not yet updated on either the KeyUp or the Change event when entering a new character. This can be fixed by substituting the Text value instead, which is updated already. Simply change line 11 to Me.Form.Filter = "[bezeichnung] LIKE '*" & SearchBoxStoffe.Text & "*'" and line 13 to Me.Form.Filter = "[bezeichnung] LIKE '*" & SearchBoxStoffe.Text & "*' AND [kategorie] = '" & Forms![HUB]![FilterAlleLink] & "'". The info originally came from #KostasK in his solution:
Keep in mind, within the Change() event, the Text property gets updated with every keystroke and when the control loses the focus, it gets copied to the Value property.
Which works too btw, just wasn't able to be verified since issue 1 prevented the code from running correctly. Answer by Kostas K.

Access VBA SQL Update - Too few Parameters expected 1

I am new to access VBA.
I am trying to add 1 to all numbers in a field that are equal or greater than the value in text box [TP_Bld_OrderNum_Txt].
This is my code:
CurrentDb.Execute "UPDATE TP_Matrix " & _
"SET TP_Matrix.Order_" & Me.TP_Bld_TP_Cbo & " = TP_Matrix.Order_" & Me.TP_Bld_TP_Cbo & "+1 " & _
"WHERE TP_Matrix.Order_" & Me.TP_Bld_TP_Cbo & ">= Me.TP_Bld_OrderNum_Txt"
I get this error:
too few parameters expected 1
I believe it relates to the text box value.
If I replace Me.TP_Bld_OrderNum_Txt with a number, the query works fine.
I have the text box set up as a number.
Why doesn't it recognize its value?
You provided Me.TP_Bld_OrderNum_Txt as a literal (as a fixed string) and not its value:
& ">= Me.TP_Bld_OrderNum_Txt"
Try this instead:
& " >= " & Me.TP_Bld_OrderNum_Txt.Value
Also, it is a good practice to use .Value to explicitely use the value of the control.

How to add a comment using comment boxes in Access?

I am building an Access database for work. I have set up a report to open upon click for a certain record. So only the information of that record is to appear on the report. However, I would like to add a comment box in the report where you can add comments. The new comments are stamped and added to the previous comments already showing in the report. I was able to program the commenting function in a separate report. However, for the reports that show only specific records it won't work. I know it is because I have to somehow add each comment to my database, but I just can not figure out how to do it. I used the following code that I found online in another article. It works fine when your comments are not tied to a certain record.
Private Sub cmdAppendComment_Click()
If (IsNull(txtNewComment.Value)) Then
MsgBox ("Please enter a comment before clicking" & _
"on the Append Comment button.")
Exit Sub
End If
' These commented lines will never be reached:
' If (IsNull(txtComment.Value)) Then
' Table.tblmain.User_comment.Value = txtNewComment.Value & " ~ " & _
' VBA.DateTime.Date & " ~ " & VBA.DateTime.Time
' Else
Table.tblmain.User_comment.Value = txtComment.Value & _
vbNewLine & vbNewLine & _
txtNewComment.Value & " ~ " & _
VBA.DateTime.Date & " ~ " & VBA.DateTime.Time
' End If
' txtNewComment.Value = ""
' Use Null:
txtNewComment.Value = Null
End Sub
You would use a form, not report, for this.
Bind this to the table, add the new comment to the existing comment bound to texbox, and save the record.

Use a cell value (text) as a part of a formula in Excel VBA

I have a problem while doing a macro in Excel VBA which looks simple but I was not able to find an answer.
What I want is to change a formula depending on a value of a concrete cell; the cell is situated in C7 and can have the text OR or the text AND. The part of the formula is (being CritEUs and CritSKUs String variables):
If CritEUs = "NO" (OR/AND) CritSKUs = "NO" Then .... (whatever)
So I want to change the OR/AND depending on the value in C7, I tried to use INDIRECT but I think it works only with numbers, and also the following (being W the Worksheet variable):
Dim Pattern As String
Pattern = W.Range("C7").Value
If CritEUs = "NO" " & Pattern & " CritSKUs = "NO" Then
But the Excel don't accept me this option.
Could it be that this is not possible?
I would really appreciate any help!
I'd look to handle this in another if statement and then nest the next if statement within like so:
Sub Example()
Dim Pattern As String
Pattern = W.Range("C7").Value
If Pattern = "AND" Then
If CritEUs = "NO" And CritSKUs = "NO" Then
'Do Something'
End If
ElseIf Pattern = "OR" Then
If CritEUs = "NO" Or CritSKUs = "NO" Then
'Do Something'
End If
End If
End Sub
Even if I strongly prefer Gareth's solution, there is a trick for doing what you want (i.e. for evaluating the condition) through the usage of the Application.Evaluate() method. It would be:
If Application.Evaluate(Pattern & "(" & Chr(34) & CritEUs & Chr(34) & "=" & Chr(34) & "NO" & Chr(34) & "," & Chr(34) & CritSKUs & Chr(34) & "=" & Chr(34) & "NO" & Chr(34) & ")") Then
... where the string being an expression such as =AND(whatever = "NO", whateverelse = "NO") or =OR(whatever = "NO", whateverelse = "NO") (depending on the value of the variable Pattern) that can be evaluated by the MS Excel application no matter what the system language is.
But as I said, I would personally prefer a nested if block as Gareth suggested because it's clearer what you are doing and it cannot crash if the user inserts an invalid logic operator or makes just a spelling mistake; you should consider this option if you don't want / cannot slightly re-design your code.
FORMULA EXPLANATION - required from the asker
The Evaluate() is a method of the Application object, which means of the object MS Excel. This method is very straightforward:
input: string
output: evaluation of the string
It is in fact used to "evaluate" a string inserted by the user exactly as it does when you type a formula into a cell. If you type into a cell "=3+4", you are basically typing Application.Evaluate("3+4"). This will return you 7, because it's the result of the string evaluation you provided.
This built-in is very very powerful, because it uses a very consolidated system (the one of MS Excel) to parse and evaluate any string that Excel can evaluate. Moreover, the evaluation is always in English (you can use the English function IF but not the Italian SE, nor the German WENN or the French SI because the method evaluates as if your Excel was in English to be system independent.
On the other hand, the Chr(34) is just returning the character ". This character is hard to use in VBA because it's usually need to separate strings (e.g. a = "first" & "second". However, you need this character inside the string to be evaluated so I'm just calling it with Chr(34) to avoid confusion of the compiler.
SUMMARY:
The string is being built up like this:
Pattern & "(" & Chr(34) & CritEUs & Chr(34) & "=" & Chr(34) & "NO" & Chr(34) & "," & Chr(34) & CritSKUs & Chr(34) & "=" & Chr(34) & "NO" & Chr(34) & ")"
Being...
Pattern = AND or OR
Chr(34) = "
... the string that we are building will be of this kind (just a possible outcome):
"AND("NO"="NO","YES"="NO")"
So, once we have built-up this string, we pass it into the Evaluate method: it's like if we were writing =AND("NO"="NO","YES"="NO") into an Excel cell. What would the outcome be? Clearly it depends on your variable, but in this case it would be FALSE, so the If - Then block will not be entered because the return value is false. Otherwise, it would be entered.
This is not a "wrong" method, but as I was saying it has only two possible downsides:
1) It needs data validation, because if you pass crap into the variable Pattern the Evaluate method will fail; in Gareth's solution, instead, only AND and OR will be evaluated, otherwise the code will skip --> more stability;
2) It's not 100% intuitive: while Gareth's solution could be explained to a 10 year old child (because it's very very straight-forward to understand), this one needs (as we just did) a deeper analysis to understand properly what it does. I.E.: you need one line of code to write it, but you/someone else that will have to work on it in the future will need 5-10 minutes and a cup of coffee to understand what the statement wants to check.

Quotation marks in VBA

In my current VBA code, I have a query in which I am using Chr(34) to put quotation marks between some of my variables.
I was wondering what alternatives exist to this. This is a simple question, i know, but I haven't had any success with repeating quotation marks like this
" & variable string here & "
My code is messy for one and not understandable for people who are not familiar with VBA:
comboService = Chr(34) & Me.Combo8.Value & Chr(34)
Also, this hasn't worked:
comboService = """" & Me.Combo8.Value & """"
Can you perhaps tell me why?
Thanks in advance.
This:
comboService = """ & Me.Combo8.Value & """
is what you posted, but you need to add an extra quotation mark in order to add a literal quotation mark:
comboService = """" & Me.Combo8.Value & """"
Double-quotes within a string are what you are looking for.
aVar = "This: "" is a literal quotation mark"
I took a page from MS (the old vbCRLF) a while back, and just define any "tricky" characters I'll need as a string at the top of my code ...
Dim vbDblQuote As String
vbDblQuote = Chr(34)
Now you can just use that pseudo-constant as you build strings ...
strMyString = "Just another string " & vbDblQuote & "with quotes" & vbDblQuote & "!"
This makes code more readable, and also helps avoid "miscounted quote errors"
I have found the same behavior if I output to a file using the Write command. Any double quotes get repeated.
However, if you construct the string and then output to file using the Print command, this does not happen and all works as expected.