Variable in function needs to be in single quotes - vb.net

I am using DataTable.Select() in VB.Net and the in the argument I need single quotes. For example:
DataTable.Select("column = 'value'")
But I want value to be a variable.
I have tried:
DataTable.Select("column = " + var ) Produces error column [var] not found
DataTable.Select("column = '" + var + "'") Produces IndexOutOfBoundsException
DataTable.Select("column = 'actual value'") Works
When using the actual value the variable holds instead of the variable it works so it must be something with the single quotes and concatenation of the variable.

There is no DataSet.Select method. There is a DataTable.Select method (documentation). I'm going to assume that you are referring to it in my answer.
Your 2nd example should work. If it is not then you will need to setup a breakpoint, inspect the value being passed to the Select method, and verify that it matches up with what you are expecting.
I would make one change and that is to use String interpolation or String.Format. This helps the code's readability.
This is a working example:
' create/seed the table
Dim table = New DataTable("Table1")
Dim column = New DataColumn("Column1")
table.Columns.Add(column)
For index = 1 To 10
table.Rows.Add({"Cell" & index.ToString()})
Next
' get value
Dim value = "Cell1"
Dim hardcodedValue = table.Select("Column1 = 'Cell1'")
Console.WriteLine(hardcodedValue(0)(0))
Dim variableValue = table.Select(String.Format("Column1 = '{0}'", value))
Console.WriteLine(variableValue(0)(0))
Fiddle: https://dotnetfiddle.net/7kZpY5

Related

Access VBA Run-time error 3078, or Type Mismatch on DCount function

Objective: I'm building VBA code to filter through an address table SunstarAccountsInWebir_SarahTest. I want to loop through first and see if the address is "valid".
If it is not valid – export to different table.
If it is valid – it enters another nested if/then within "valid" address rows:
If their ID, external_nmad_id matches the ID of the second table 1042s_FinalOutput_7, I want to update one of the columns in the second table box13c_Address.
If it doesn't match an ID of the second table – it will be exported to a different table.
My problem is when I run my code it is returning
Run-Time error 3078: cannot find table or query
(it's breaking at the line where I compare the value of the cell (as string) against the DCount of table 2). If I remove the quotes around it I get a different error:
Type mismatch against the DCount
I feel like I'm missing something simple but can't tell what. How can I get my code to match a string value called in !external_nmad_id against the rest of the table called in my string? DCount("[ID]", StrSQL1)
Public Sub EditFinalOutput2()
'set variables
Dim i As Long
Dim qs As DAO.Recordset
Dim ss As DAO.Recordset
Dim StrSQL1 As DAO.Recordset
Dim IRSfileFormatKey As String
Dim external_nmad_id As String
Dim nmad_address_1 As String
Dim nmad_address_2 As String
Dim nmad_address_3 As String
Dim mytestwrite As String
'open reference set
Set db = CurrentDb
Set qs = db.OpenRecordset("SunstarAccountsInWebir_SarahTest")
'Set ss = db.OpenRecordset("1042s_FinalOutput_7")
'Set StrSQL1 = db.OpenRecordset("SELECT RIGHT(IRSfileFormatKey, 10) As ID
'FROM 1042s_FinalOutput_7;")
With qs.Fields
intCount = qs.RecordCount - 1
For i = 0 To intCount
If (IsNull(!nmad_address_1) Or (!nmad_address_1 = !nmad_city) Or (!nmad_address_1 = !Webir_Country) And IsNull(!nmad_address_2) Or (!nmad_address_2 = !nmad_city) Or (!nmad_address_2 = !Webir_Country) And IsNull(!nmad_address_3) Or (!nmad_address_3 = !nmad_city) Or (!nmad_address_3 = !Webir_Country)) Then
DoCmd.RunSQL "INSERT INTO Addresses_ToBeReviewed SELECT SunstarAccountsInWebir_SarahTest.* FROM SunstarAccountsInWebir_SarahTest WHERE (((SunstarAccountsInWebir_SarahTest.external_nmad_id)='" & qs!external_nmad_id & "'));"
Else:
Set ss = db.OpenRecordset("1042s_FinalOutput_7")
Set StrSQL1 = db.OpenRecordset("SELECT RIGHT(IRSfileFormatKey, 10) As ID FROM 1042s_FinalOutput_7;")
If !external_nmad_id = DCount("[ID]", StrSQL1) Then
ss.Edit
ss.Fields("box13c_Address") = qs.Fields("nmad_address_1") & qs.Fields("nmad_address_2") & qs.Fields("nmad_address_3")
ss.Update
Else: DoCmd.SetWarnings False
DoCmd.RunSQL "INSERT INTO Addresses_NotUsed SELECT SunstarAccountsInWebir_SarahTest.* FROM SunstarAccountsInWebir_SarahTest WHERE (((SunstarAccountsInWebir_SarahTest.external_nmad_id)='" & qs!external_nmad_id & "'));"
DoCmd.SetWarnings True
End If
End If
qs.MoveNext
Next i
End With
'close reference set
qs.Close
Set qs = Nothing
ss.Close
Set ss = Nothing
End Sub
The issue is that the DCount function cannot operate directly against a Recordset.
You are declaring StrSQL1 as a RecordSet object and setting it to a RecordSet based on your Select statement.
Set StrSQL1 = db.OpenRecordset("SELECT RIGHT(IRSfileFormatKey, 10) As ID FROM 1042s_FinalOutput_7;")
You are then trying to pass this RecordSet to the DCount function which cannot accept a RecordSet object as the Domain parameter. As you can see in MSDN the DCount function requires a String parameter in the second position to define the "query" that you wish to "Count". Hence the 3078 error. When you remove the quotes around [ID] in your DCount line, you get Type Mismatch as a compile error because [ID] is not a String or String variable.
After you resolve that, you might want to reconsider your If statement. You haven't provided a sample of what kind of value !external_nmad_id will contain, other than the fact that it is a String value. The DCount function is going to return the number of rows found in the Domain (query) that you told it to count, so it appears you will be comparing a string (which may possibly contain alpha characters) to a number. Access will implicitly convert the DCount numeric result to a String for the sake of the comparison, but if your !external_nmad_id String is truly 10 characters or contains alpha characters, they will never match.
You cannot use a VBA recordset inside a domain aggregate like DCount as a string literal is required for table/query name argument. Simply save your query and then reference it by name in DCount.
SQL (save as query)
SELECT RIGHT(IRSfileFormatKey, 10) As ID FROM 1042s_FinalOutput_7;
VBA
If !external_nmad_id = DCount("[ID]", "mySavedQuery") Then
...
End If

String.replace adding extra characters

I am trying to replace some words in mails in Outlook. Here is my code for it
Dim input As String = mail.HTMLBody
Dim pattern As String = "QWQ[a-z][a-z][0-9][0-9][0-9][0-9][0-9]"
Dim replacement As String
Dim rgx As New Regex(pattern)
Dim match As Match = Regex.Match(input, pattern)
While (match.Success)
replacement = "A" + match.Value + "A"
input = input.Replace(match.value, replacement)
match = match.NextMatch()
End While
mail.HTMLBody = input
For this input
QWQrt12345
QWQrt1234533
wwQWQrt12345
QWQrt1234534
qwwQWQrt12345
I expect output as
AQWQrt12345A
AQWQrt12345A33
wwAQWQrt12345A
AQWQrt12345A34
qwwAQWQrt12345A
But the output I am getting is
AAAAAQWQrt12345AAAAA
AAAAAQWQrt12345AAAAA33
wwAAAAAQWQrt12345AAAAA
AAAAAQWQrt12345AAAAA34
qwwAAAAAQWQrt12345AAAAA
What can be the issue?
The description of String.Replace states,
Returns a new string in which all occurrences of a specified string in
the current instance are replaced with another specified string.
The important takeaway there is, "all occurrences ... are replaced." Since your replacement string is also a match for your regular expression pattern, it will be replaced (thus adding another set of 'A') upon every iteration.
Try a test case using something like this, instead:
replacement = match.Value.Replace("Q", "A")
The details here don't matter (you can change whatever you want), the point is that you change something so that your strings aren't matched repeatedly.
simply put your adding 'A' + match + 'A' evertytime you match .
Resulting in the AAAAA before and after your input. I've been voted down?
ok I explain your first match input result is exactly what you have inputted(all characters could be matched), you then add "A" both sides and want to replace your replaced value with the original value.
Here's the c# code to get expected value :
var input = "QWQrt1234533"; //your second line example
const string pattern = "QWQ[a-z][a-z][0-9][0-9][0-9][0-9][0-9]";
var rgx = new Regex(pattern);
Match match = Regex.Match(input, pattern);
while (match.Success)
{
var replacement= "A" + match.Value + "A";
input = input.Replace(match.Value, replacement);
match = match.NextMatch();
}
Console.Write(input);
resulting in your exected : "AQWQrt12345A33"
not getting your results even with the posted VB code (you did not edit the original after my first response?)

Find a variable with concatenation

I would like to find a variable with concatenation.
Exemple :
Dim oExcelRangeArray1(0, 0) As Object
Dim oExcelRangeArray2(0, 0) As Object
Dim oExcelRangeArray3(0, 0) As Object
For i As Integer = 1 To 3
oExcelRangeArray & i = xl.Range("A1:Z400").Value
Next
but oExcelRangeArray & i doesn't work.
Thank you
For the extent of my knowledge, there is no way to achieve what you are trying to do directly, because oExcelRangeArray & i will not be evaluated as a separate step before the variable assignment happens.
In my mind you have two choices:
Assign each variable individually,
oExcelRangeArray1 = x1.Range("A1:Z400").Value
oExcelRangeArray2 = x1.Range("A1:Z400").Value
oExcelRangeArray3 = x1.Range("A1:Z400").Value
oExcelRangeArray4 = x1.Range("A1:Z400").Value
Or, add each array to a list, and iterate through it,
Dim oExcelRangeArrayList As New List(Of Object)
oExcelRangeArrayList.Add(oExcelRangeArray1)
oExcelRangeArrayList.Add(oExcelRangeArray2)
oExcelRangeArrayList.Add(oExcelRangeArray3)
oExcelRangeArrayList.Add(oExcelRangeArray4)
For i As Integer = 0 To 3
oExcelRangeArrayList(i) = x1.Range("A1:Z400").Value
Next
[Note: Writing this freehand without checking it, code may not be verbatim; hopefully you get the concept. Corrections welcome.]

vba function which returns more than one value and so can be called in sql

I'm new to VBA and i need help.
I want to create vba function which takes table name as input, and distinct specific field from that table. I created function, and it works when i run it in vba immediate window (when i use debug.print command to display results). But when i call this function in sql, instead whole field values, it returns just last one. I'm not good at vba syntax so i need help to understand. Does function can return more than one value? If can, how, and if not what else to use? Here's my code:
Public Function TableInfo(tabela As String)
Dim db As Database
Dim rec As Recordset
Dim polje1 As Field, polje2 As Field
Dim sifMat As Field, pogon As Field, tipVred As Field
Set db = CurrentDb()
Set rec = db.OpenRecordset(tabela)
Set sifMat = rec.Fields("Field1")
Set pogon = rec.Fields("Field2")
Set tipVred = rec.Fields("Field3")
For Each polje1 In rec.Fields
For Each polje2 In rec.Fields
TableInfo = pogon.Value
rec.MoveNext
Next
Next
End Function
Any help is appreciated.
The problem is with this line probably:
TableInfo = pogon.Value
It runs inside the loop and returns the last value of the loop.
Instead of returning one value TableInfo, you may try to return something similar to a Collection or an Array.
Inside the loop, append values in the Collection and after the loop, return the Collection back from the function.
Edit:
I have re-written the code shared by you:
Public Function TableInfo(tabela As String) as String()
Dim db As Database
Dim rec As Recordset
Dim polje1 As Field, polje2 As Field
Dim sifMat As Field, pogon As Field, tipVred As Field
Dim returnValue() As String
Dim i as Integer
Set db = CurrentDb()
Set rec = db.OpenRecordset(tabela)
Set sifMat = rec.Fields("Field1")
Set pogon = rec.Fields("Field2")
Set tipVred = rec.Fields("Field3")
' I am not going to modify this but I think we can do away with two For Each loops.
' Just iterate over rec like
' For Each r In rec -> please use proper naming conventions and best practices
' and access each field as r("Field1") and r("Field2")
For Each polje1 In rec.Fields
For Each polje2 In rec.Fields
returnValue(i) = pogon.Value
i = i + 1
rec.MoveNext
Next
Next
TableInfo = returnValue
End Function
Please note: I have not tested this code but I assume this should work for you. Also, I have assumed that you want to return String() array. Please change the data type if you want to return some other type.
When you call the array (as posted in theghostofc's answer), you will need to do something like this:
Dim TableInfo() As String
For i = LBound(TableInfo) To UBound(TableInfo)
YourValue = TableInfo(i)
... Process some code that uses YourValue
Next i
If you're not looping through your array, you're not going to get each individual value out of it.

how to get value by split in vb.net 2005

i have a database in one field like below 222-225. I try to make split to read that value for my function. Just simple function a=225 b=222 then total=(a-b)+1. here my code
Dgv.CellClick
'Dim x As Boolean
Dim a As Double
Dim total As Double
a = CDbl(Dgv.Item(8, Dgv.CurrentRow.Index).Value)
Split(a, "-")
total = (a) - (a)
Dgv.Item(9, Dgv.CurrentRow.Index).Value = total
My problem is this doesn't work. I can't get the value that I split. Any idea how to solve this problem?
note: I use VB.NET 2005
If you want total=(a-b)+1 .. That should be
dim b = a.Split("-")
total = val(b(1)) - val(b(2)) + 1
may be this can help. try this...
Dim a As String
a = ""
Dim x As String
Dim total As Double
a = Dgv.Item(8, Dgv.CurrentRow.Index).Value.ToString
Dim ary() As String
x = a
ary = x.Split("-")
total = CInt(ary(1)) - CInt(ary(0))
Dgv.Item(9, Dgv.CurrentRow.Index).Value = total
Like others have said, Split() returns a String array, like this:
Dim SplitValue() As String = Split(a, "-")
total = (CType(SplitValue(1), Double) - CType(SplitValue(0), Double)) + 1
If I read your question correctly, the value you're looking for is 222-225, and that value is located in the specified cell of Dgv (which I'm guessing is a DataGridView). If my understanding is correct, there are a couple of things going on.
First, I'm not sure why you're trying to convert that value to a double with the following line of code:
a = CDbl(Dgv.Item(8, Dgv.CurrentRow.Index).Value)
The Item property of a DataGridView holds a DataGridViewCell, and the Value property of the DataGridViewCell returns an Object. Trying to convert 222-225 to a double will, I believe, fail (though since this is VB.NET, it's possible it won't depending on the options you set - I'm not as familiar with VB.NET as I am with C#).
Even if it does successfully work (I'm not sure what the output would be), Split expects a string. I would change that line of code to the following:
a = Dgv.Item(8, Dgv.CurrentRow.Index).Value.ToString()
Now you have a string that you can use Split on. The Split you have in your posted code appears to be the Visual Basic (pre-.NET) Split method Split Function (Visual Basic). As others have mentioned, Split returns an array of strings based on the delimiter. In your code, you don't assign the result of Split to anything, so you have no way to get the values.
I would recommend using the .NET version of Split (String.Split Method) - there are several ways you can call String.Split, but for purposes of your code I'd use it like this:
Dim splits As String() = a.Split(New Char() { "-" })
Where a is the string value from the selected DataGridViewCell above. This will give you a 2-element array:
splits(0) = "222"
splits(1) = "225"
The final part is your formula. Since you have strings, you'll need to convert them to a numeric data type:
total = (CDbl(splits(1)) - CDbl(splits(0))) + 1
Which becomes (225 - 222) + 1 = 4.
Putting it altogether it would look something like this:
Dim a As String
Dim total As Double
Dim splits() As String
a = Dgv.Item(8, Dgv.CurrentRow.Index).Value.ToString()
splits = a.Split(New Char() { "-" })
total = (CDbl(splits(1)) - CDbl(splits(0))) + 1
Dgv.Item(9, Dgv.CurrentRow.Index).Value = total
Split returns an array. something like this. VB.Net is not my primary language but this should help.
dim arr = a.Split(New Char (){"-"})
total = ctype(arr(0), double) - ctype(arr(1),double)
Try this:
Dim aux() As String = a.Split("-"c)
total = CDbl(aux(0)) - CDbl(aux(1)) + 1
Dim a As string
Dim x As String
Dim total As Double
a = Dgv.Item(8, Dgv.CurrentRow.Index).Value
Dim ary() As String
x = a
ary() = x.Split("-")
total = CInt(ary(1)) - CInt(ary(0))
Dgv.Item(9, Dgv.CurrentRow.Index).Value = total