How to loop through a row in each column even the data is NULL or empty string? - vb.net

I have a VB.NET program which runs as a Windows Service. All it does is connect to a table in SQL Server 2016 and reads data (if any exist) and does some transaction posting to an ERP System. Now in that table (ALL_LABOR_DETAILS) I have 29 columns and some of them could be 'NULL' or empty string value per given row. You can see I've used IsDBNull function for those columns only in my code.
Following is my code which I'm moving through the rows and columns in the dataset but I've noticed whenever it comes to a row with a 'NULL' value for operationComplete or strDefaultBin or strLotNo column it does not read is as a Empty String, instead it tries to move to another row with no NULL record and read that row instead.
Also it throws me this error in my log file whenever it encounters a NULL value in
operationComplete
Error: Conversion from type 'DBNull' to type 'String' is not valid.
Code:
Dim postCount3 As SqlDataReader
Dim newServer3 As String = ConfigurationManager.AppSettings("newServer")
Try
Using cn3 As New SqlConnection(newServer3),
cmd3 As New SqlCommand(Sql3, cn3)
cn3.Open()
postCount3 = cmd3.ExecuteReader()
If postCount3.HasRows Then
While postCount3.Read()
Try
SourceID = Trim(postCount3.Item(0))
strSourceName = Trim(postCount3.Item(1))
strOrderNumber = Trim(postCount3.Item(4))
strItemNumber = Trim(postCount3.Item(11))
strOperationNumber = Trim(postCount3.Item(7))
strCurrentStatus = Trim(postCount3.Item(2))
strDepartment = Trim(postCount3.Item(5))
strWorkCenter = Trim(postCount3.Item(6))
strOperator = Trim(postCount3.Item(8))
strTrxDate = Trim(postCount3.Item(3))
strPosted = Trim(postCount3.Item(14))
totalLaborHrs = Trim(postCount3.Item(9))
laborFeetProduced = Trim(postCount3.Item(10))
If Not IsDBNull(Trim(postCount3.Item(22))) Then
operationComplete = Trim(postCount3.Item(22))
Else
operationComplete = Trim(postCount3.Item(22)).ToString()
End If
If Not IsDBNull(Trim(postCount3.Item(13))) Then
strDefaultBin = Trim(postCount3.Item(13))
Else
strDefaultBin = Trim(postCount3.Item(13)).ToString()
End If
If Not IsDBNull(Trim(postCount3.Item(12))) Then
strLotNo = Trim(postCount3.Item(12))
Else
strLotNo = Trim(postCount3.Item(12)).ToString()
End If
FileIO.WriteLog("")
'Print Source ID
FileIO.WriteLog(SourceID)
'Print Source Name
FileIO.WriteLog(strOrderNumber & " Source Name = " & strSourceName)
'Print Order Number
FileIO.WriteLog(strOrderNumber & " Order Number = " & strOrderNumber)
'Print Item Number
FileIO.WriteLog(strOrderNumber & " Item Number = " & strItemNumber)
'Print Operation Number
FileIO.WriteLog(strOrderNumber & " Operation Number = " & strOperationNumber)
'Print Department
FileIO.WriteLog(strOrderNumber & " Department = " & strDepartment)
'Print Work Center
FileIO.WriteLog(strOrderNumber & " Work Center = " & strWorkCenter)
'Print Operator
FileIO.WriteLog(strOrderNumber & " Operator = " & strOperator)
'Print Current Status
FileIO.WriteLog(strOrderNumber & " Current Status = " & strCurrentStatus)
'Print Total Labor Hours
FileIO.WriteLog(strOrderNumber & " Total Labor Hours = " & totalLaborHrs)
'Print Labor Feet Produced
FileIO.WriteLog(strOrderNumber & " Labor Feet Produced = " & laborFeetProduced)
'Print Operation Complete
FileIO.WriteLog(strOrderNumber & " Operation Complete = " & operationComplete)
'Print Default Bin
FileIO.WriteLog(strOrderNumber & " Default Bin = " & strDefaultBin)
'Print Lot No
FileIO.WriteLog(strOrderNumber & " Lot No = " & strLotNo)
Catch ex As Exception
FileIO.WriteLog("Error : " & ex.Message)
End Try
Continue While
End While
postCount3.Close()
cn3.Close()
End Using
Catch ex As Exception
FileIO.WriteLog(strOrderNumber & " There was an error getting the laborDetails FROM ALL_LABOR_DETAILS table WHERE posted = '' AND work_order IS NOT NULL ORDER BY SOURCE_ID. Error Message : " & ex.Message)
End Try

You are trying to Trim DBNull. Try changing this(the Else)
operationComplete = Trim(postCount3.Item(22)).ToString()
to
operationComplete = postCount3.Item(22).ToString()
Same for the others.

You cannot implicitly cast dbnull to a string which is what youa redoing with the trim command. It accepts a string parameter and vb tries to cast. If null is an option, I would recommend tryParse.
Y organization uses a wrapper class to parse the value of return a nothing for these sorts of calls. The class structure is simple enough and looks something like the below though with a string we return string.empty.
Public Module Parsers
Function ParseString(value as object) as String
Dim result as string
If String.TryParse(value, result) then
Return result
End if
Return string.empty
End function
End module
And then call it like
strSourceName = Trim(Parsers.ParseString(postCount3.Item(1)))

Related

How do I concatenate a variable of the type Date/Time in my Insert statement

This runs when the form loads:
Private Sub Form_Load()
TempVars("F_ID") = txtF_SNr.Value
TempVars("Status") = txtStatus.Value
TempVars("seit") = txtSeit.Value
TempVars("bis") = txtBis.Value
TempVars("von") = txtVon.Value
TempVars("an") = txtAn.Value
TempVars("Bemerkung") = txtBemerkung.Value
End Sub
txtSeit is the name of the text field in my form, bound to the column [seit] with the type of Date/Time in my table.
sql = "Insert into tblStatusFahrzeugeHistory (F_ID, Status, seit, bis, von, an, Bemerkung, Datenbank_Nutzer, Eintrag_erstellt_am, Eintrag_erstellt_um)" & _
"Select tblStatusFahrzeuge.F_ID, tblStatusFahrzeuge.Status, tblStatusFahrzeuge.seit, tblStatusFahrzeuge.bis, tblStatusFahrzeuge.von, tblStatusFahrzeuge.an, tblStatusFahrzeuge.Bemerkung, tblStatusFahrzeuge.Datenbank_Nutzer, tblStatusFahrzeuge.Eintrag_erstellt_am, tblStatusFahrzeuge.Eintrag_erstellt_um " & _
"From tblStatusFahrzeuge Where ( " & txtSeit.Value & " <> seit AND [F_ID] = '" & Me.txtF_SNr.Value & "') "
The sql statement above gives me the error:
runtime error: '3075' syntax error in number in query expression...
How do I concatenate txtSeit.Value correctly? (Sorry im a beginner!)

Looping through table to find value from a textbox

I'm trying to loop through a column inside a table from a form in Access to find out whether a "Case Name" already exists or not, and if it does not, then add the new record to the table. I want the criteria to be based on the input value of a text box. The good news is I have figured out how to add a new record to the table with the code below. I'm just stuck on how to loop through a table to find out if a record already exists. Thanks in advance!
Private Sub SaveNewCase_Click()
If Me.txtNewCaseName.Value <> "Null" And Me.txtCaseDepth.Value <> "Null" And Me.txtCaseHeight2.Value <> "Null" And Me.txtCaseWeight.Value <> "Null" And Me.txtCaseWidth <> "Null" And Me.cboCaseCategory.Value <> "Null" Then
'I think the loop should go here, but not sure'
CurrentDb.Execute "INSERT INTO tblCases(CaseName, CaseWidth, CaseHeight, CaseCasters, CaseWeight, CaseDepth, CaseCategory) " & _
" VALUES ('" & Me.txtNewCaseName & "'," & Me.txtCaseWidth & "," & Me.txtCaseHeight2 & ",'" & Me.chkboxCasters & "'," & Me.txtCaseWeight & "," & Me.txtCaseDepth & ",'" & Me.cboCaseCategory & "')"
Else
MsgBox "Please enter all new case criteria."
End If
End Sub
Firstly, use parameters!
Concatenating values supplied by a user directly into your SQL statement exposes your to SQL injection, either intentional (i.e. users entering their own SQL statements to sabotage your database) or unintentional (e.g. users entering values containing apostrophes or other SQL delimiters).
Instead, represent each of the field values with a parameter, for example:
With CurrentDb.CreateQueryDef _
( _
"", _
"insert into " & _
"tblcases (casename, casewidth, caseheight, casecasters, caseweight, casedepth, casecategory) " & _
"values (#casename, #casewidth, #caseheight, #casecasters, #caseweight, #casedepth, #casecategory) " _
)
.Parameters("#casename") = txtNewCaseName
.Parameters("#casewidth") = txtCaseWidth
.Parameters("#caseheight") = txtCaseHeight2
.Parameters("#casecasters") = chkboxCasters
.Parameters("#caseweight") = txtCaseWeight
.Parameters("#casedepth") = txtCaseDepth
.Parameters("#casecategory") = cboCaseCategory
.Execute
End With
Since the value of each form control is fed directly to the parameter within the SQL statement, the value will always be interpreted as a literal and cannot form part of the SQL statement itself.
Furthermore, you don't have to worry about surrounding your string values with single or double quotes, and you don't have to worry about formatting date values - the data is used in its native form.
Where testing for an existing value is concerned, you can either use a domain aggregate function, such as DLookup, or you could use a SQL select statement and test that no records are returned, e.g.:
Dim flg As Boolean
With CurrentDb.CreateQueryDef _
( _
"", _
"select * from tblcases where " & _
"casename = #casename and " & _
"casewidth = #casewidth and " & _
"caseheight = #caseheight and " & _
"casecasters = #casecasters and " & _
"caseweight = #caseweight and " & _
"casedepth = #casedepth and " & _
"casecategory = #casecategory " _
)
.Parameters("#casename") = txtNewCaseName
.Parameters("#casewidth") = txtCaseWidth
.Parameters("#caseheight") = txtCaseHeight2
.Parameters("#casecasters") = chkboxCasters
.Parameters("#caseweight") = txtCaseWeight
.Parameters("#casedepth") = txtCaseDepth
.Parameters("#casecategory") = cboCaseCategory
With .OpenRecordset
flg = .EOF
.Close
End With
End With
If flg Then
' Add new record
Else
' Record already exists
End If
Finally, you're currently testing the values of your form controls against the literal string "Null", which will only be validated if the user has entered the value Null into the control, not if the control is blank.
Instead, you should use the VBA IsNull function to check whether a variable holds a Null value.

Use bookmark value in WORD for sql query

I am currently trying to build an automated WORD business letter that fills out corresponding data such as company address, company name, today's date, deadline date and so on after I have typed in a 5 digit number.
The number and all other fields are bookmarks.
Whenever the user types in a specific 5 digit number into the bookmark named "theNumber", this value will be used for an SQL query (Oracle). The query then fills out all other bookmarks!
Here is what I have tried so far:
Function dbQuery(ByVal TM As String, ByVal myNumber As String) As Boolean
Dim sqlrumpf As String
Dim sqlstring As String
Dim connstring As String
With ActiveDocument
If .Bookmarks.Exists(TM) Then
Dim TMRange As Range
Set TMRange = .Bookmarks(TM).Range
TMRange = myNumber
.Bookmarks.Add TM, TMRange
dbQuery = True
Else
Debug.Print "Bookmark not found: " & TM
End If
End With
sqlrumpf = "SELECT p.name " & _
"FROM xy.person p, xy.adresse a, wz.zusatz1 z, xy.vorgang v " & _
"WHERE p.adresse_id = a.adresse_id " & _
"AND z.aktnr = v.vorgang_id " & _
"AND a.adresse_id = v.adresse_id " & _
"AND v.vorgang_nr = '"
sqlstring = sqlrumpf & myNumber & "'"
connstring = "ODBC;DSN=mydsn;UID=myuid;DBQ=my.dbq.lan;DBA=W;APA=T;PFC=1;TLO=0;PWD=mypw;"
QueryTables.Add _
(Connection:=connstring, _
Destination:=Range(TMRange), _
Sql:=sqlstring).Refresh
End Function
Sub Main()
If dbQuery("theNumber", "12345") = False Then
MsgBox "Database query failed!"
End If
End Sub
I get the error:
Runtime Error '4608': Value not within definition range.
How can I fix this?
The error seems to occur here:
Destination:=Range(TMRange), _
Normally I use this query only for excel when I want to print a query into a single cell.
Is it generally a bad idea to use bookmarks with sql queries in this manner?
Which fields would you use if not bookmarks?
How do you query bookmark values?

SQL Exception SQL0206: Column or global variable is not found

I connected to the database, and want to get some data. However, got the SQL Exception said that SQL0206: Column or global variable ADDDATE not found.
Here's the related code:
Function ConnectToiSeries() As Boolean
Dim conSQL As String
conSQL = "Provider = IBMDA400; Data Source = xxxxxxx; User ID = xxxxx; Password = xxxxxxx"
coniseries.ConnectionTimeout = 30
coniseries.Open(conSQL)
If coniseries.State <> ADODB.ObjectStateEnum.adStateOpen Then
Console.WriteLine("Error, Try Again.")
Return False
Exit Function
Else
Console.WriteLine("Connected.")
Return True
End If
End Function
Function GetDocuments(ByRef ClientRS as Adodb.recordset) As Boolean
Dim i As Integer
Dim ClientID As String
Dim AttachmentName As String
Dim Status As String
Dim AdditionalFile As String
Dim SQLStm As String
If CheckedListBox1.CheckedItems.Count > 0 Then
Dim s As String = ""
For i = 0 To (CheckedListBox1.CheckedItems.Count - 1)
s = s + "No." & (i + 1).ToString & ":" & CheckedListBox1.CheckedItems.Item(i).ToString & ControlChars.CrLf
MessageBox.Show("You are Choosing:" & ControlChars.CrLf & s)
Dim SQLStm As String
SQLStm = "Select APFIVCCLA.APP, APFIVCCLA.CLIENT, APFIVCCLA.CLIENTID, APFATTACH.ATTTYP, APFATTACH.ATTPATHNAM, APFIVCCLA.INCSPTDOC, APFATTACH.ADDDATE" &
ControlChars.CrLf & "From CPASDLIB.APFATTACH, CPASDLIB.APFIVCCLA" & ControlChars.CrLf &
"Where APFIVCCLA.App = 'Simple Legal' And APFIVCCLA.ATTKEY = '" & CheckedListBox1.CheckedItems.Item(i) &
"' AND APFIVCCLA.Client = APFATTACH.ATTKEY And APFATTACH.ADDDATE = '" & Rundate & "'" & ControlChars.CrLf & " Order by APFIVCCLA.Client"
ClientRS.Open(SQLStm, coniseries)
The SQLStm sentences can be run, and can get results, but don't know why not work for this program.
Here's the full Error Message:
Exception thrown: 'System.Runtime.InteropServices.COMException' in
SLBS.exe An unhandled exception of type
'System.Runtime.InteropServices.COMException' occurred in SLBS.exe
SQL0206: Column or global variable ADDDATE not found. Cause . . . . .
: ADDDATE was not found as a column of table *N in *N and was not
found as a global variable in *N. If the table is *N, ADDDATE is not a
column of any table or view that can be referenced. Recovery . . . :
Do one of the following and try the request again: -- Ensure that the
column and table names are specified correctly in the statement. -- If
this is a SELECT statement, ensure that all the required tables were
named in the FROM clause. -- If the column was intended to be a
correlated reference, qualify the column with the correct table
designator. -- If the column was intended to be a global variable,
qualify the name with the schema where the global variable exists or
ensure the schema is in the path.
Thanks.

Removing first character from a column if it starts with 0

I have an oracle table, a_abc that have three columns (name, ID and address). The data for this table will be extracted from a txt file. How to remove the first character in ID column if it starts with number '0'. I need a VB solution. This is what Ive done so far now
Private Sub ReadData()
Dim rowvalue As String
Dim cellvalue(20) As String
Dim header As String = "ID"
Dim streamReader As IO.StreamReader = New IO.StreamReader("D:\local_costctr.txt")
'Reading CSV file content
While streamReader.Peek() <> -1
rowvalue = streamReader.ReadLine()
cellvalue = rowvalue.Split("|") 'check what is ur separator
ConnectOracle()
mySQLcmd.Connection = myConn
If SQL.Length > 0 Then
SQL.Replace(SQL.ToString, "")
End If
SQL.Append("insert into a_abc (name ,ID ,address) ")
SQL.Append(" values ('" & cellvalue(0) & "' ,'" & cellvalue(1) & "','" & cellvalue(2) & "') ")
Console.WriteLine(header)
Console.WriteLine(header.Trim({"0"c}))
Try
mySQLcmd.CommandText = SQL.ToString
mySQLcmd.ExecuteNonQuery()
Catch ex As Exception
MessageBox.Show("Error " & ex.Message.ToString)
End Try
End While
End Sub
If there is more than one leading zero, I want all of them removed.
The ltrim function should do the trick:
SELECT name, LTRIM(id, '0'), address
FROM a_abc
EDIT:
Now that the question was edited, I see you refer inserting the data, not querying it. The same solution could be applied on an insert too though:
SQL.Append("insert into a_abc (name ,ID ,address) ")
SQL.Append(" values ('" & cellvalue(0) & "', LTRIM(" & cellvalue(1) & ", '0'), '" & cellvalue(2) & "') ")
While you are extracting the data from the txt-file and you come across the ID-field:
For Each line As String In IO.File.ReadAllLines("yourpath")
If "myID".Substring(0, 1) = "0" Then
'take the "myID" without the leading 0
"myID".Substring(1)
End if
Next
Depending on your case you might need Null-checks etc...
Edited for your code:
Replace cellvalue(1) in the SQL.append by:
IIF(cellvalue(1).Substring(0, 1) = "0",cellvalue(1).Substring(1),cellvalue(1))