How to populate column based on other columns - sql

I need to understand why this does not work in MS Access:
UPDATE main_records
SET main_records.rece = Str(main_records.Nr) & "," & Str(main_records.Pag);
The intent is to populate the rece column (63 chars string) in all records of main_records with the contents of Nr and Pag (converted to string and concatenated).
It looks so easy but ...

"the contents of Nr and Pag (converted to string and concatenated)"
If that is what you intend to do, you are to use a string conversion function
examples is
CStr( expression ).

Related

Long Query Execution through VBA concatenation

I'm setting up an automated excel vba workbook that extracts data through a Query, while getting the parameters from Excel cells.
So far it has worked on simple Queries and SPs but I'm trying to pass a very long query and it seems Excel Functions is truncating the string to 1043 chars.
*The query has 1426 chars.
I've taken 3 different approaches to this problem.
Executing a SQL stored procedure (from vba) rather than a query, the problem is one of the input parameters is a list of ids, which is variable in length, and very long to pass as an SP parameter, so it hasn't worked even when assigning Varchar(Max) as type.
Executing the query into a new table, and extracting the full table into excel. While this does work it makes it necessary to update the id list manually, hence it's not functional enough.
Passing the SQL string directly to the Excel function as a concatenation of strings, but it throws the error which I believe relates to the string truncate.
My code is as follows:
Private Sub CommandButton1_Click()
Dim organization As Integer 'Business Unit
Dim material As String 'List of IDs
organization = Sheets("Hoja1").Range("B3").Value 'Extract B3
material = Sheets("Hoja1").Range("B4").Value 'Extract B4
'Parsing the query into statements to be concatenated
Connection
With ActiveWorkbook.Connections("NZSQL Test").ODBCConnection
sql1 = 'statement1
sql2 = 'statement2
sql3 = 'statement3
sql4 = 'statement4
sql5 = 'statement5
sql6 = 'statement6
Query = sql1 & sql2 & sql3 & sql4 & sql5 & sql6
Sheets("Hoja1").Range("B2") = Query 'This is to beused as revision directly
in ODBC platform
.CommandText = Query
ActiveWorkbook.Connections("NZSQL Test").Refresh
End With
End Sub
The resultset I'm getting when pasting the B2 query in SQL:
/*
ERROR [42000] ERROR: '...' 'Returns a part of the SQL string */
The string here is truncated to 1043 chars.
However, I have tried the same approach from Python using pyodbc and it works perfectly.
Have you tried explicitly declaring your Query variable as a string with your other declarations in the sub?
Dim Query As String
According to here, a string can:
A variable-length string can contain up to approximately 2 billion (2^31) characters.
A fixed-length string can contain 1 to approximately 64 K (2^16) characters.
Hopefully that helps.

Excel VBA insert array variable into single field in access

In my project I'm trying to save indefinite entry in excel sheet into the database (access). I'm trying to use vba to do so. However, because I don't know how long the entries will be, and I can't create so many fields in the database to fit the unknown amount of entries. And I can't INSERT an array variable into one field in the table. How can I do this?
Say I have below.
Dim SN(100) As String
SN(0)=123 'value of each entry
SN(1)=2412
'so on and so many entries
Then in the SQL statement,
"INSERT INTO [TableName] ([FieldName]) Values (SN)"
It will say RunTime Error "13" Type mismatch.
Is there any way the database field can accept a list or array as data type? So when I call the data out I can use the index to call the variable inside the list?
MS Access does not have such a data type, more primitive types like string, boolean, long. But consider joining all items in array using Join into a single string and save that string to database table. Then use Split to pull back into array as needed:
Sub ArrayIntoSQL()
Dim SN(100) As String, TN() As String
Dim SNstr As String,
SN(0) = 123 'value of each entry'
SN(1) = 2412
SNstr = Join(SN, "|") ' PIPE DELIMITER '
'123|2412|||||||||||||||||||||||||||||||||||||||||||||_
||||||||||||||||||||||||||||||||||||||||||||||||||||||'
strSQL = "INSERT INTO [TableName] ([FieldName]) Values ('" & SNstr & "')"
...
End Sub
Sub ArrayOutofSQL()
Dim SN() As String
Dim SNstr As String
strSQL = "SELECT [FieldName] FROM [TableName]"
...
Do While Not rst.EOF
SN() = Split(rst!FieldName, "|")
rst.MoveNext
Loop
...
End Sub
Because the array items may exceed Access' 255 character limit for short text data type, use the long text type (previously called memo) which does not have a declared limit.
However for best practices, wide tables (many columns) and stored objects like arrays in fields are more expensive than long tables (many rows) and linked objects. So simply save data iteratively:
For Each item in SN
strSQL = "INSERT INTO [TableName] ([FieldName]) Values (" & item & ")"
...
Next item
Of course, save values with an identifier like ID, Person, Date!

using IndexOf in Mid function

Perhaps this is a simple solution for most, but I can't get this to work like it should according to syntax.
I have this line of text "Part Number123456Price$50.00"
I want to pull the part number out of it, so I use this function...
str = Mid(str, str.IndexOf("Part Number") + 12, str.IndexOf("Price"))
My results are str = "123456Price$50.0" every time. I know the part number can vary in length so I need a solid solution of pulling this out.
It can be confusing to mix the legacy VB string methods (such as Mid) with the .Net string methods (like IndexOf). The VB methods use 1 as the index of the first character while the .Net methods use 0.
The following code will extract the part number from a string
Dim str As String = "Part Number123456Price$50.00"
Dim iPart As Integer = str.IndexOf("Part Number") + 11
Dim iPrice As Integer = str.IndexOf("Price")
str = str.Substring(iPart, iPrice - iPart).Trim
The Mid() function of Visual Basic is documented as having three arguments: (1) a string, (2) the beginning location in the string, and (3) the number of characters to copy.
So if your string is "Part Number123456Price$50.00" and you want to pull the part number as a series of digits, the "123456" part of the string, using the Mid() function then you need to find the beginning of the part number digit string and to then know the number of digits.
If your string is in the variable str then you can find the offset by something like str.IndexOf("Number") + len("Number") which will provide the offset to after the string "Number".
Next you need to find the number of digits so you would do something like str.IndexOf("Price") to find where the text "Price" begins and then subtract from that offset the offset of where the digits begin.
The result of all of this is you need a bit of code something like the following. I have not tested this source as I am not a VB programmer so it may need a tweak and you might want to put some checks on data validity as well.
Dim TextNumber as String = "Number"
Dim TextPrice as String = "Price"
iOffset = str.IndexOf(TextNumber) + len(TextNumber)
str = Mid(str, iOffset, str.IndexOf(TextPrice) - iOffset)
Alternatively, if Price is always the format $00.00, this will also work.
Dim str as String = "Part Number123456Price$50.00"
str = str.Remove(str.IndexOf("Price"))

Creating an Array from a CSV text file and selecting certain parts of the array. in VB.NET

Ive searched over and over the internet for my issue but I havent been able to find / word my searches correctly...
My issue here is that I have a Comma Separated value file in .txt format... simply put, its a bunch of data delimited by commas and text qualifier is separated with ""
For example:
"So and so","1234","Blah Blah", "Foo","Bar","","","",""
"foofoo","barbar","etc.."
Where ever there is a carriage return it signifies a new row and every comma separates a new column from another.
My next step is to go into VB.net and create an array using these values and having the commas serve as the delimeter and somehow making the array into a table where the text files' format matches the array (i hope im explaining myself correctly :/ )
After that array has been created, I need to select only certain parts of that array and store the value into a variable for later use....
Andthats where my trouble comes in... I cant seem to get the correct logic as to how to make the array and selecting the certain info out of it..
If any
You might perhaps give a more detailed problem description, but I gather you're looking for something like this:
Sub Main()
Dim fileOne As String = "a1,b1,c1,d1,e1,f1,g1" + Environment.NewLine + _
"a2,b2,c2,d2,e2,f2,g2"
Dim table As New List(Of List(Of String))
' Process the file
For Each line As String In fileOne.Split(Environment.NewLine)
Dim row As New List(Of String)
For Each value In line.Split(",")
row.Add(value)
Next
table.Add(row)
Next
' Search the "table" using LINQ (for example)
Dim v = From c In table _
Where c(2) = "c1"
Console.WriteLine("Rows containing 'c1' in the 3rd column:")
For Each x As List(Of String) In v
Console.WriteLine(x(0)) ' printing the 1st column only
Next
' *** EDIT: added this after clarification
' Fetch value in row 2, column 3 (remember that lists are zero-indexed)
Console.WriteLine("Value of (2, 3): " + table(1)(2))
End Sub

EDIFACT How to group, spilt, sort and sum up values from a EDI string into variables in VB.NET

I am new to VB.Net 2008. I have a tricky task to resolve, it is regarding extracting characters (values) from a long string, the extracted values from the text shall be summed up and sorted by keywords, reformatted and saved into a CSV file.
It looks something like this but much longer :
UNH+RAM6957'COMPANY1BY500C10'ZEW+REQEST6957'COMPANY2SL200C20'COMPANY1SL300C10'ZEW
The values are seperated by ' .
As first step I splitted the string to make it readable, I used the function like:
Dim LineOfText As String
Dim i As Integer
Dim aryTextFile() As String
LineOfText = p_EDI
aryTextFile = LineOfText.Split("'")
For i = 0 To UBound(aryTextFile)
Console.WriteLine((aryTextFile(i)))
Next i
Now the result looks like:
UNB+UNOA:1+CCP:ZEW+STE:ZEW+100901:1200+2010917283
UNH+M000001+ORDRSP:D:96A:UN:EGT102
BGM+02G::ZEW+NOMRES24364+34
DTM+Z05:0:805
DTM+137:201009011000:203
DTM+Z01:201009090400201009100400:719
RFF+AHI:GSCOMPANY1
NAD+ZSO+CCP::ZEW
NAD+ZSH+GSSTATKRAFT::ZEW
TDT+41G++70
LOC+Z11+:::TTF
LIN+1+23
LOC+Z11+:::TTF
QTY+Z05:0:KW1
DTM+2:201009090400201009100400:719
NAD+ZUS+GSBNP::ZEW
LIN+2+23
LOC+Z11+:::TTF
QTY+Z05:0:KW1
DTM+2:201009090400201009100400:719
NAD+ZUS+GSBPA::ZEW
So far so good:
Now I have to extract the date and time from the header:
The line looks like:
**DTM+137**:201009011000:203 should look like
DTM+137:2010.09.01-10:00:203 and store it into a 'incomming_DTM' variable for example
Now the message period would be interresting to know:
The line looke like:
**DTM+Z01**:201009090400201009100400:719 the output should look like:
DTM+Z01 2010.09.09-04:00, 2010.09.10-04:00 and store it into 'period_DTM' variable
As next step I need to parse the next lines until it reaches the KEYWORD LIN
Like:
LIN+1+23
LOC+Z11+:::TTF
QTY+Z05:0:KW1
DTM+2:201009090400201009100400:719
NAD+ZUS+GSBNP::ZEW
NAD+ZSH+COMPANY1RPH N001::ZEW (P Character in word -> SELL QTY:0 KW/h)
LIN+2+23
LOC+Z11+:::TTF
QTY+Z05:0:KW1
DTM+2:201009090400201009100400:719
NAD+ZUS+GSBPA::ZEW
NAD+ZSH+COMPANY1RRH N001::ZEW (R Character in word -> BUY QTY:0 KW/h)
and store the KEYWORDS "QTY" "DTM" "NAD+ZSH" and its following Characters
into variables.
THEN I need to parse until it reaches the next LIN Keyword and store the
keywords there into vaiables again. The goal of this complicated exercise is,
to sum up values of QTY and NAD+ZSH+COMPANY1RVH and NAD+ZSH+COMPANY1RPH
If we have a closer look at the last zwo charaters in COMPANY1RRH and COMPANY1RPH
we see RH and PH, RH means buy and PH means sell.
Maybe it is possible to store BUY or SELL into a Contract vaiable for each LIN?
I need to sum up all sells and buys which where found in the string.
Every LIN marks a time period of one hour, so we have probably 24 series per
string which contains 24 LIN every LIN have a Time period, BUY or SELL keywords
and a Quantity.
Can someone please help me with this task?
As first step, storing the keywords and its follwoing characters into variables would
be a very good start. It might be very good to do that probably until the parser reaches the LIN, then store the found values into a CSV file or Array?, then parse until the next LIN and so on...
I would like to create a CSV file out of the results like: So the CSV should contain
24 records one per every hour per every LIN..
Dim csvData = Now & "," & "TRADED_QTY" & "," & DTM+Z01 & "," & "N" & "," & QTY & "," & "KWH/h" & "," & Contract
Console.WriteLine(csvData)
Creating the CSV File with True Flag -> Append data to CSV.
Dim csvFile As String = "C:\Test.csv"
Dim outFile As IO.StreamWriter = My.Computer.FileSystem.OpenTextFileWriter(csvFile, True)
Any ideas are highly welcome, I consider this as very complex task
espacial as I am really new to VB.NET.
Thank you in advance!
I see "EDI" in your code. If this is an EDI format, then you should have, or be able to get, some kind of EDI specification. Likely, it will be a fixed-length specification, meaning that "Value X is characters 1 to 9", "Value Y is characters 10 to 11", "Value Z is character 12", etc.
Here is one possible approach to parse out the KEYWORDS as first step:
Dim EDI As Object
EDI = dataReader(0)
'Convert EDI Object into a string and write it to the console.
Dim p_EDI As String = Convert.ToString(EDI)
'Create LineBreaks after every " ' "
Dim LineOfText As String
Dim i As Integer
Dim aryTextFile() As String
LineOfText = p_EDI
aryTextFile = LineOfText.Split("'")
'Starting with IF clause to find keywords
For Each line As String In aryTextFile
Console.WriteLine(line)
If line.StartsWith("UNB") Then
Dim foundUNB_Data = p_EDI.IndexOf("UNB")
'Start at that position and extract UNB + 27 characters
Dim UNBData = EDI.Substring(foundUNB_Data, 30)
Console.WriteLine(UNBData)
ElseIf line.StartsWith("LIN") Then
.
.
ElseIf line.StartsWith("QTY") Then
.
.
End If
Next
Any further ideas are highly welcome..
Thank you.