Passing variables between subs inside class - arrays

This may have been asked and answered several times, but I have been unable to find the answer.
In CbProdukt1_SelectedIndexChanged(), I need the associated value from an array from another sub:
Private Sub CbProdukt1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CbProdukt1.SelectedIndexChanged
With Me.LblEnhed1
.Text = Enhed(CbProdukt1.SelectedIndex)
.Location = New Point(230, 150)
End With
Me.Controls.Add(LblEnhed1)
End Sub
This would be easy enough if Enhed() had been public. But it is not as it is dimensioned and retrieved from Sqlite in another sub:
Dim count As Integer
sql = "SELECT COUNT(varenr) AS varenrcount FROM '" & Varedatabase & "'"
cmd = New SQLiteCommand(sql, conn)
count = cmd.ExecuteScalar
sql = "SELECT * FROM '" & Varedatabase & "'"
cmd = New SQLiteCommand(sql, conn)
reader = cmd.ExecuteReader
Dim a = 0
Dim Varenr(count + 5) As String
Dim Varenavn(count + 5) As String
Dim Enhed(count + 5) As String
While (reader.Read())
Varenr(a) = reader("varenr")
Varenavn(a) = reader("Varenavn")
Enhed(a) = reader("Enhed")
CbProdukt1.Items.Add(varenavn(a))
a += 1
End While
Public declarations are only allowed prior to subs at the top of the class.
So how do I get the Enhed(a) from sub to sub?

Related

How to assign a String variable to a dataset?

I read rows from a file, do a check on the first row and then I have to write the next rows of the file into a table called "TestTable" with a method that works on DataSet. It tells me that I can't insert the string type in DataSet.
Dim myStream As Stream = Nothing
Dim openFileDialog1 As New OpenFileDialog()
openFileDialog1.InitialDirectory = "Z:\FitalogItalia\KMaster\SPEKM" 'ATTENZIONE CAMBIARE IN "C:\"
openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*"
openFileDialog1.FilterIndex = 2
openFileDialog1.RestoreDirectory = True
If openFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
Try
myStream = openFileDialog1.OpenFile()
If (myStream IsNot Nothing) Then
Dim objReader As New StreamReader(openFileDialog1.FileName)
Dim ControlLine As String = ""
Dim sLine As String = ""
Dim arrText As New ArrayList()
ControlLine = objReader.ReadLine
If (ControlLine.Contains("H06") And ControlLine.Contains("SPEKM")) Then
sLine = objReader.ReadLine
Dim indice As Integer = 0
Do
If Not sLine Is Nothing Then
arrText.Add(sLine)
DB_SQL.SetDBfromDataset("INSERT INTO TestTable (riga) VALUES (" + arrText.Item(indice) + ");", "TestTable")
indice = +1
End If
Loop Until objReader.ReadLine.Count - 1
End If
objReader.Close()
End If
Catch Ex As Exception
MessageBox.Show(Ex.Message)
Finally
' Check this again, since we need to make sure we didn't throw an exception on open.
If (myStream IsNot Nothing) Then
myStream.Close()
End If
End Try
End If
UPDATE I ADDED THE FUNCTION WITH WHICH I LOAD THE DATA ON THE DB. THE PROBLEM IS THE ARRAY LIST BECAUSE I NEED TO PASS A DATASET
Public Function SetDBfromDataset(ByVal ds As Data.DataSet, ByVal TN As String) As Integer
DBadapter.InsertCommand = New SqlCommand
TmpSQLstring = "INSERT INTO " & TN
' ottengo la lista dei campi
ListFields = " ("
For Each myCol In ds.Tables(0).Columns
If (Not IsPrimaryCol(myCol, PKcols)) And (NormalizeDataTypeToDBtype(myCol) <> SqlDbType.Timestamp) Then
ListFields = ListFields & Trim(myCol.ColumnName)
ListFields = ListFields & ","
End If
Next
ListFields = Mid$(ListFields, 1, Len(ListFields) - 1) & ")"
'ottengo la lista dei parametri
ListParam = " VALUES ("
For Each myCol In ds.Tables(0).Columns
If (Not IsPrimaryCol(myCol, PKcols)) And (NormalizeDataTypeToDBtype(myCol) <> SqlDbType.Timestamp) Then
ListParam = ListParam & "#" & Trim(myCol.ColumnName)
ListParam = ListParam & ","
DBadapter.InsertCommand.Parameters.Add(New SqlParameter("#" & Trim(myCol.ColumnName), NormalizeDataTypeToDBtype(myCol)))
DBadapter.InsertCommand.Parameters("#" & Trim(myCol.ColumnName)).SourceColumn = Trim(myCol.ColumnName)
End If
Next
ListParam = Mid$(ListParam, 1, Len(ListParam) - 1) & ")"
DBadapter.InsertCommand.CommandText = TmpSQLstring & ListFields & ListParam
DBadapter.InsertCommand.Connection = CType(DBadapter.SelectCommand.Connection, SqlConnection)
End Function
Streams need to be disposed by calling Dispose or placing in a Using block. This is a text file so you don't even need a stream.
ArrayList is around for backward compatibility but you shouldn't be used in new code. See https://learn.microsoft.com/en-us/dotnet/api/system.collections.arraylist?view=net-5.0#remarks A good replacement is List(Of T)
I have broken the code into 3 methods. You are doing too many separate tasks in a single method. I have used System.IO.File class to read the file. ReadAllLines returns an array of the lines in the file. Then a simple For Each loop to identify the lines you want to add to the database. I used a List(Of String) to collect the lines. Then pass the list to the database code in InsertText.
Only the value of the parameter changes in the loop.
Private Sub OPCode()
Dim FilePath = GetFilePath()
If FilePath Is Nothing Then
MessageBox.Show("No file selected.")
End If
Dim lst As New List(Of String)
Dim lines = File.ReadAllLines(FilePath)
For Each line In lines
If line.Contains("H06") AndAlso line.Contains("SPEKM")) Then
lst.Add(line)
End If
Next
InsertText(lst)
End Sub
Private Function GetFilePath() As String
Dim openFileDialog1 As New OpenFileDialog()
openFileDialog1.InitialDirectory = "Z:\FitalogItalia\KMaster\SPEKM" 'ATTENZIONE CAMBIARE IN "C:\"
openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*"
openFileDialog1.FilterIndex = 2
openFileDialog1.RestoreDirectory = True
If openFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
Return openFileDialog1.FileName
Else
Return Nothing
End If
End Function
Private Sub InsertText(lst As List(Of String))
Using cn As New SqlConnection("Your connection string"),
cmd As New SqlCommand("INSERT INTO TestTable (riga) VALUES (#riga);", cn)
cmd.Parameters.Add("#riga", SqlDbType.NVarChar)
cn.Open()
For Each line In lst
cmd.Parameters("#riga").Value = line
cmd.ExecuteNonQuery()
Next
End Using 'closes the connection and disposes the command and the connection
End Sub

Auto generate alpha numeric in VB.NET

I'm currently working on my project for which I used VB.NET 2019 and SQL server. I need to create a function which auto generates IDs.
I want my IDs to be like these: P001, P002, P003 etc. Can someone show me how to code it? Below is my code
Private Sub Form4_Load_1(sender As Object, e As EventArgs) Handles MyBase.Load
BindData()
Dim data As String = "Data Source=LAPTOP-M8KKSG0I;Initial Catalog=Oceania;Integrated Security=True"
Dim con As New SqlConnection(data)
Try
If Con.State = ConnectionState.Closed Then
con.Open()
End If
Dim sql As String = "Select Max(PatientID) from Patient"
Dim cmd As New SqlCommand(sql, con)
Dim Max As String = cmd.ExecuteScalar
If Max > 0 Then
TextBox1.Text = Max + 1
Else
TextBox1.Text = "P01"
End If
Catch ex As Exception
MsgBox(Err.Description)
End Try
End Sub
You can try like this. Here 1 is an auto-generated number that may be an identity key column value from a table in SQL Server.
Dim number As Integer = 1
Dim numberText As String = "P" & number.ToString().PadLeft(3, "0")
Live demo
You can add a computed column like this in your table for auto-generating the sequences. This will reduce the chances of duplicate value runtime once more than one person will do the entry simultaneously.
Alter table Patient ADD PatientCode AS ('P' + Convert(Varchar(3),CONCAT(REPLICATE('0', 3 - LEN(PatientID)), PatientID)) )
To get the column value dynamically you can try the below code to generate function.
Private Sub GenerateSequnce()
Dim constring As String = "Data Source=TestServer;Initial Catalog=TestDB;User id = TestUser;password=test#123"
Using con As New SqlConnection(constring)
Using cmd As New SqlCommand("Select Top 1 ISNULL(TaxCode, 0) from Tax_Mst Order By TaxCode Desc", con)
cmd.CommandType = CommandType.Text
Using sda As New SqlDataAdapter(cmd)
Using dt As New DataTable()
sda.Fill(dt)
Dim maxNumberCode = dt.Rows(0)("TaxCode").ToString()
If (maxNumberCode = "0") Then
maxNumberCode = "1"
End If
Dim numberText As String = "P" & maxNumberCode.ToString().PadLeft(3, "0")
End Using
End Using
End Using
End Using
End Sub
Here the column TaxCode is int with identity constraint.
With the minor correction in your code, you can achieve this as shown below.
Dim data As String = "Data Source=LAPTOP-M8KKSG0I;Initial Catalog=Oceania;Integrated Security=True"
Dim con As New SqlConnection(data)
Try
If con.State = ConnectionState.Closed Then
con.Open()
End If
Dim sql As String = "Select ISNULL(Max(PatientID), 0) from Patient"
Dim cmd As New SqlCommand(sql, con)
Dim Max As String = cmd.ExecuteScalar
If (Max = "0") Then
Max = "1"
Else
Max = CInt(Max) + 1
End If
Dim numberText As String = "P" & Max.ToString().PadLeft(3, "0")
TextBox1.Text = numberText
Catch ex As Exception
MsgBox(Err.Description)
End Try
OUTPUT

error in code vb.net import data from access to sdf

enter image description hereI am using a SQL Server Compact 3.5 database file (.sdf) in vb.net
There was an error parsing the query. [Token line number,Token line offset,,Token in error,,]
Dim flag As Boolean
Dim flag2 As Boolean
Me.OpenFileDialog1.Filter = "mdb files (*.mdb)|"
Me.OpenFileDialog1.Filter = "mdb files (*.mdb)|*.mdb|All files (*.*)|*.*"
flag2 = (Me.OpenFileDialog1.ShowDialog() = DialogResult.OK)
If flag2 Then
flag = (Operators.CompareString(FileSystem.Dir(Me.OpenFileDialog1.FileName, FileAttribute.Normal), "", False) <> 0)
End If
Dim myConnectionStringMDB As String = "provider=Microsoft.Ace.OLEDB.12.0;" & "data source=" & Me.OpenFileDialog1.FileName
Dim myConnectionStringSQL As String = "Provider=Microsoft.SQLSERVER.CE.OLEDB.3.5;" & "Data Source=" & Application.StartupPath & "\Archive.sdf"
Using conSQL As OleDbConnection = New OleDbConnection(), conMDB As OleDbConnection = New OleDbConnection()
conSQL.ConnectionString = myConnectionStringSQL
conSQL.Open()
conMDB.ConnectionString = myConnectionStringMDB
conMDB.Open()
Using cmdSQL As OleDbCommand = New OleDbCommand(), cmdMDB As OleDbCommand = New OleDbCommand()
cmdMDB.CommandType = Data.CommandType.Text
cmdMDB.Connection = conMDB
cmdMDB.CommandText = "SELECT * FROM [student]"
Dim daMDB = New System.Data.OleDb.OleDbDataAdapter(cmdMDB)
Dim dt = New Data.DataTable()
daMDB.Fill(dt)
For Each dr As Data.DataRow In dt.Rows
' change row status from "Unchanged" to "Added" so .Update below will insert them
dr.SetAdded()
Next
cmdSQL.CommandType = Data.CommandType.Text
cmdSQL.Connection = conSQL
cmdSQL.CommandText = "SELECT * FROM [student]"
Dim daSQL = New System.Data.OleDb.OleDbDataAdapter(cmdSQL)
Dim cbuilderMDB = New OleDbCommandBuilder(daSQL)
cbuilderMDB.QuotePrefix = "["
cbuilderMDB.QuoteSuffix = "]"
daSQL.Update(dt)
End Using
conSQL.Close()
conMDB.Close()
End Using
I got rid of the extra boolean variables flag and flag2 and just tested the values directly.
I divided the Using blocks into 2 blocks so the first group of objects can be closed and disposed before the next group starts their work.
I shortened the code by passing properties directly to the constructors of the objects where possible. DataAdapter and StringBuilder also expose a .Dispose method so I included them in the Using blocks.
daMDB.AcceptChangesDuringFill = False
This line of code allows the .DataRowState to remain as Added (normally it is changed to Unchanged by the .Fill method) so, the DataTable will be ready to add all the records to the second table without the loop.
I don't believe that student is a reserved word in either database so I removed the square brackets.
Both the .Fill and the .Update methods of the DataAdapter will .Open and .Close the connection if they find the connection closed. If they find it open they will leave it open. So, closing the connection is not necessary. Also the End Using closes and disposes all objects included in the Using portion (first line including commas) of the block.
Private Sub OPCode()
OpenFileDialog1.Filter = "mdb files (*.mdb)|*.mdb|All files (*.*)|*.*"
Dim MDBFile As String
If OpenFileDialog1.ShowDialog = DialogResult.OK AndAlso Not String.IsNullOrEmpty(OpenFileDialog1.FileName) Then
MDBFile = OpenFileDialog1.FileName
Else
Exit Sub
End If
Dim myConnectionStringMDB As String = "provider=Microsoft.Ace.OLEDB.12.0;" & "data source=" & MDBFile
Dim myConnectionStringSQL As String = "Provider=Microsoft.SQLSERVER.CE.OLEDB.3.5;" & "Data Source=" & Application.StartupPath & "\Archive.sdf"
Dim dt = New Data.DataTable()
Using conMDB As OleDbConnection = New OleDbConnection(myConnectionStringMDB),
cmdMDB As OleDbCommand = New OleDbCommand("SELECT * FROM student", conMDB),
daMDB As New System.Data.OleDb.OleDbDataAdapter(cmdMDB)
daMDB.AcceptChangesDuringFill = False
daMDB.Fill(dt)
End Using
Using conSQL As OleDbConnection = New OleDbConnection(myConnectionStringSQL),
cmdSQL As OleDbCommand = New OleDbCommand("SELECT * FROM student", conSQL),
daSql As New OleDbDataAdapter(cmdSQL),
cbuilderMDB As New OleDbCommandBuilder(daSql)
daSql.Update(dt)
End Using
End Sub

Parametrizing dynamic sql query (VB.Net)

I have an unsecured query which allows for an injection, and I'm not sure how to go about parameterizing it to prevent said injection
Dim sInsertSQL As String
sInsertSQL = "Insert into tbl_userprop (Prop_Def) values "
Dim tempString As String() = PropertyDefinitions.Split("|")
For i As Integer = 1 To tempString.Length
If tempString(i - 1).Length > 0 Then
sInsertSQL = sInsertSQL + " ('" + tempString(i - 1) + "'),"
bInsert = True
End If
Next
There are up to 10 values stored in tempString and they are concatenated onto sInsertSQL as such: ('val1'), ('val2'), etc
Figured it out, update for the curious:
Dim lstParams As New Collections.Generic.List(Of SqlParameter)
Dim tempString As String() = PropertyDefinitions.Split("|")
For i As Integer = 1 To tempString.Length
If tempString(i - 1).Length > 0 Then
Dim sParamName As String = String.Format("#param{0}", i)
Dim sparam As New SqlParameter(sParamName, tempString(i - 1))
lstParams.Add(sparam)
sInsertSQL = sInsertSQL + " (" + sParamName + "),"
bInsert = True
End If
Next
Once you have split the string you know how many parameters there will be, so you can create the # items for the SQL. After that, you can add the parameters by going through the lists of parameter names and values:
Dim PropertyDefinitions = "abc|def|ghi|jkl|mno"
Dim values = PropertyDefinitions.Split({"|"c})
Dim paramNames = Enumerable.Range(0, values.Count()).Select(Function(n) $"#p{n}")
Dim paramList = String.Join(", ", paramNames.Select(Function(s) $"({s})"))
Dim sql = "INSERT INTO [tbl_userprop] (Prop_Def) VALUES " & paramList
' The following line with the sample data would output '
' INSERT INTO [tbl_userprop] (Prop_Def) VALUES (#p0), (#p1), (#p2), (#p3), (#p4)
'Console.WriteLine(sql)
Dim connStr = "YourConnectionStringHere"
Using conn As New SqlConnection(connStr)
Using cmd As New SqlCommand(sql, conn)
For i = 0 To values.Count() - 1
'TODO: Set the .SqlDbType and .Size to conform to the database definition of [tbl_userprop]. '
cmd.Parameters.Add(New SqlParameter With {.ParameterName = paramNames(i),
.Value = values(i),
.SqlDbType = SqlDbType.NVarChar,
.Size = 99})
Next
'conn.Open()
'cmd.ExecuteNonQuery()
End Using
End Using

import excel in datagrid view vb.net

I'm trying to import Excel in datagridview using this methods in the code below. But I have an error in this line "invalidOperationException" can't get the data to show up
cnnExcel.Open()
and here is the whole code
comboBox as cmbExcel
Having some if condition for supporting depend on excel version (2003 - 2013)
Imports System.Data.OleDb
Public Class Form1
Dim cnnExcel As New OleDbConnection
Public Function GetExccelSheetNames() As String()
Dim ConStr As String = ""
Dim dt As DataTable = Nothing
Dim opExcel As New OpenFileDialog
opExcel.Filter = "(*.xlsx)|*.xlsx|(*.xls)|*.xls"
opExcel.ShowDialog()
Dim pathExcel As String = opExcel.FileName
If pathExcel.Trim = "" Then
MessageBox.Show("Please Select Excel File !")
Return Nothing
Else
Dim Ext As String = pathExcel.Substring(pathExcel.LastIndexOf(".") + 1)
If Ext.Length = 3 Then
ConStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pathExcel + ";Extended Properties='Excel 8.0;HDR=Yes;IMEX=1';"
ElseIf Ext.Length = 4 Then
ConStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + pathExcel + ";Extended Properties='Excel 12.0 xml;HDR=YES';"
End If
cnnExcel = New OleDbConnection(ConStr)
cnnExcel.Open()
dt = cnnExcel.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing)
If dt Is Nothing Then
Return Nothing
End If
Dim excelSheetNames As [String]() = New [String](dt.Rows.Count - 1) {}
Dim i As Integer = 0
For Each row As DataRow In dt.Rows
excelSheetNames(i) = row("TABLE_NAME").ToString()
i += 1
Next
cnnExcel.Close()
Return excelSheetNames
End If
End Function
Added a Button as btnBrows to brows excel file from any location in local drive
Private Sub btnBrowse_Click(sender As Object, e As EventArgs) Handles btnBrowse.Click
cmbsheet.DataSource = GetExccelSheetNames()
End Sub
Dim dt As New DataTable
Then Finally having a button to view the excel in datagridview
Private Sub btnShow_Click(sender As Object, e As EventArgs) Handles btnShow.Click
Dim cmd As New OleDbCommand("Select * from [" + cmbsheet.SelectedValue.ToString() + "]", cnnExcel)
cnnExcel.Open()
dt.Clear()
dt.Load(cmd.ExecuteReader())
cnnExcel.Close()
DataGridView1.DataSource = dt
End Sub
End Class
Use this as a reference. It's 100% working. I'm using this in one of my applications. Put this code on your import button.
Dim result As DialogResult = OpenFileDialog1.ShowDialog()
Dim path As String = OpenFileDialog1.FileName
Me.TextBox1.Text = path.ToString
Try
Me.dgvFile.DataSource = Nothing
Dim MyConnection As System.Data.OleDb.OleDbConnection
Dim MyCommand As System.Data.OleDb.OleDbDataAdapter
MyConnection = New System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" & Me.TextBox1.Text & "';Extended Properties=Excel 8.0;")
MyCommand = New System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", MyConnection)
MyCommand.TableMappings.Add("Table", "Net-informations.com")
DtSet = New System.Data.DataTable
MyCommand.Fill(DtSet)
Me.dgvFile.DataSource = DtSet
MyConnection.Close()
MessageBox.Show("File successfully imported")
Catch ex As Exception
MessageBox.Show("Error")
End Try

Resources