I am creating an inventory management system in VB.Net, where the basic function is the process incoming invoices. I would like to insert data into my remote MySQL database but only if the textbox is considered enabled. I have no issue inserting data into the database when I want it to insert all fields. But I would like to have checkboxes enable certain products and allow the employees to enter only specific items. The check boxes do enable and disable the text fields as required but when inserting data into the database it will enter null values for all product types and I don't want it doing that as it will mess up the invoicing system. Currently I tried an if then statement but the issue I ran into was that it wanted the not enabled textboxes to be defined.
Code for what I tried is:
Public Sub btnEnter_Click(sender As Object, e As EventArgs) Handles btnEnter.Click
Dim mysqlconn as new MySqlConnection ("ServerConnection")
mysqlconn.Open()
dim mysqlCmd as new MysqlCommand
mysqlcmd.Connection = MysqlConn
mysqlcmd.CommandText = "Insert into Table_Name (Column1,Column2,Column3) Values (#rec1,#Rec2,#Rec3)"
If txtTextbox1.Enabled = True then
mysqlcmd.Parameters.AddWithValue("#Rec1",Column1.text)
End If
If txtTextBox2.Enabled = True then
mysqlcmd.Parameters.AddWithValue(#Rec2,Column2.text)
End IF
IF txtTextBox3.Enabled = True then
mysqlcmd.Parameters.AddWithValue(#Rec3,Column3.text)
End If
You can't just insert a column without a row. So if you will insert one column, you must insert all columns. If you don't want to add a value, then the column could be NULL or empty string, depending on the columns in the database. Also use Using and take the database work off the UI with Async/Await
Public Async Sub btnEnter_Click(sender As Object, e As EventArgs) Handles btnEnter.Click
' if your columns take NULL to mean no value
Await AddParams(
If(txtTextbox1.Enabled, Column1.Text, Nothing),
If(txtTextbox2.Enabled, Column2.Text, Nothing),
If(txtTextbox3.Enabled, Column3.Text, Nothing))
' else, if an empty string means no value
Await AddParams(
If(txtTextbox1.Enabled, Column1.Text, ""),
If(txtTextbox2.Enabled, Column2.Text, ""),
If(txtTextbox3.Enabled, Column3.Text, ""))
End Sub
Private Function AddParams(param1 As String, param2 As String, param3 As String) As Task
Return Task.Run(
Sub()
Using mysqlconn As New MySqlConnection("ServerConnection")
mysqlconn.Open()
Using mysqlCmd As New MySqlCommand("Insert into Table_Name (Column1,Column2,Column3) Values (#rec1,#Rec2,#Rec3)", mysqlconn)
mysqlCmd.Parameters.AddWithValue("#Rec1", param1)
mysqlCmd.Parameters.AddWithValue("#Rec2", param2)
mysqlCmd.Parameters.AddWithValue("#Rec3", param3)
End Using
End Using
End Sub)
End Function
If I understand your current design,
Table_Name
ID
Column1
Column2
Column3
1
abc
def
ghi
2
jkl
mno
pqr
An incomplete invoice has empty string or NULL when one column isn't enabled
ID
Column1
Column2
Column3
1
abc
NULL
ghi
2
NULL
mno
pqr
This is what this answer does.
If your database design is flexible, perhaps a better design would be
Invoice
ID
Name
1
Invoice 1
2
Invoice 2
InvoiceRec
ID
Name
1
Column1
2
Column2
3
Column3
InvoiceItem
ID
InvoiceID
InvoiceRecID
Value
1
1
1
abc
2
1
3
ghi
3
2
2
mno
4
2
3
pqr
Now you aren't storing any null when an item is not enabled. The SQL to select would then be
SELECT
i.Name InvoiceName
, ir.Name InvoiceRecName
, ii.Value Value
FROM InvoiceItem ii
INNER JOIN Invoice i ON i.ID = ii.InvoiceID
INNER JOIN InvoiceRec ir ON i.ID = ir.InvoiceRecID
WHERE i.Name = 'Invoice 1'
InvoiceName
InvoiceRecName
Value
Invoice 1
Column1
abc
Invoice 1
Column3
ghi
This would totally invalidate the code I wrote (except keep the Async and Using) and you'd need to query multiple tables before making multiple inserts, but the design would be normalized and database storage size would be reduced.
Further, you can build your UI from the metadata tables [Invoice] and [InvoiceRec] so if wanted to add another InvoiceRec to your business, you can add in SQL, and the UI will not need to be modified.
Related
I have imported an existing excel file and created it as table 'Product' in access. It already has rows of existing data. I have created a form based on the table for data entry.
I would like to enter multiple values in the ProductNo cell separated by a comma ( as shown below)
PID (PK - Autonum)
PCR
ProductNo
Title
Unit
Dept
Date
Comments
PCR1
p210en, p213es, p217er
PCR1 title description
2
D1
1/23/21
fdsfsdf
and saving the record, it has to split the cell values and save it as multiple records in the backend product table.
PID (PK - Autonum)
PCR
ProductNo
Title
Unit
Dept
Date
Comments
PCR1
p210en
PCR1 title description
2
D1
01/23/2021
fdsfsdf
PCR1
p213es
PCR1 title description
2
D1
01/23/2021
fdsfsdf
PCR1
p217er
PCR1 title description
2
D1
01/23/2021
fdsfsdf
I don't want to edit the existing data in Product. It correctly reflects only one value in the ProductNo. I want to update only the values entered in the form.
I have looked for similar vba codes and found ones that modifies data in the existing table.
I have worked with SQL before but not much with Access/VBA code. I have programming knowledge. Any help is appreciated. Thank you :)
Updated -- Possible Solution:
So this is what I have done. I have a created a temporary table 'TempProduct' that I have used to input the data and when I click on save button, I have the following vba code that splits the cell data in multiple records and adds it to the original table.
enter code here
Option Compare Database
Private Sub Command11_Click()
Dim db As Database
Dim rs1 As Recordset
Dim rs2 As Recordset
Set db = CurrentDb()
Dim sqlStr, fieldStr As String
Dim i As Integer
sqlStr = "Select PCR, ProductNo, Title, Unit, Dept, Date, Comments from TempProduct"
Set rs1 = db.OpenRecordset(sqlStr)
Set rs2 = db.OpenRecordset("Product")
Do While Not rs1.EOF
fieldStr = rs1.Fields(1)
If InStr(fieldStr, ",") > 0 Then
myString = Split(fieldStr, ",")
For i = LBound(myString) To UBound(myString)
rs2.AddNew
rs2!PCR = rs1!ECRNo
rs2!ProductNo = myString(i)
rs2!Title = rs1!Title
rs2!Unit = rs1!Unit
rs2!Dept = rs1!Dept
rs2!Date = rs1!Date
rs2!Comments=rs1!Comments
rs2.Update
Next i
Else
rs2.AddNew
rs2!PCR = rs1!ECRNo
rs2!ProductNo = rs1!ProductNo
rs2!Title = rs1!Title
rs2!Unit = rs1!Unit
rs2!Dept = rs1!Dept
rs2!Date = rs1!Date
rs2!Comments=rs1!Comments
rs2.Update
End If
rs1.MoveNext
Loop
DoCmd.RunSQL ("Delete * from TempProduct")
End Sub
And it kind of works. Though the multiple records are pushed from the form into the product table only when a new record is added again. i.e. the first record entered in the form are split and entered into the product table only after the second set of records are entered in the form.
Any suggestions as how I can push the records immediately. Thanks a bunch.
I am using Access Database to get a value. I am fairly new to access as I usually use SQLServer and I am having trouble in getting what I want.
I have the following table, with column TARGET and incremental Target as the target column that I need to get:
Category|Period|Value| TARGET |
A | 4 | 1 | 1/1 =1 |
A | 3 | 3 | 1/(3*1)=0.33 | (1/value at period 3 * previous target)
A | 2 | 6 |1/(0.33*6)=0.505|
A | 1 | 9 |1/(0.505*9)=0.22|
The data is partitioned by Category and ordered in descending order by Period.
For the first row the Target should be: (1/value at current period)
For the next rows the Target should be: (1/value at current period * value of previous target)
As you can see this is somehow complex as I need to evaluate a cell value and then for the next row I need to use the value in the cell above.
Plus I need to get the incremental value for this column as well.
Any help will be very much appreciated as I am new to Access and need to get this done soon!
Here is a function placed in general module that can be called from query. Value is a reserved word so I used Data for that field name.
Option Compare Database
Option Explicit
Global dblTar As Double
Global strCat As String
____________
Function CalcTarget(strC As String, dblT As Double) As Double
If strCat <> strC Then
strCat = strC
dblTar = dblT
End If
dblTar = 1 / (dblT * dblTar)
CalcTarget = dblTar
End Function
Calling function in query:
SELECT Category, Period, Data, CalcTarget([Category],[Data]) AS Target FROM Table1;
Normally I advise not to save calculated data to table when a query can work, but if you prefer to save, then options are:
An UPDATE action: UPDATE Table1 SET Target = CalcTarget([Category],[Data]);
Or VBA:
Sub CalcTarget()
Dim rs As DAO.Recordset
Dim strCat As String
Dim dblTar As Double
Set rs = CurrentDb.OpenRecordset("SELECT * FROM table1 ORDER BY Category, Period DESC")
strCat = rs!Category
dblTar = rs!Data
Do While Not rs.EOF
If rs!Category = strCat Then
dblTar = 1 / (rs!Data * dblTar)
rs.Edit
rs!Target = dblTar
rs.Update
rs.MoveNext
Else
strCat = rs!Category
dblTar = rs!Data
End If
Loop
End Sub
I'm very new to vb.net and LINQ to SQL.
I have been trying the whole day to do this but it doesn't seem to work at all. all your help is highly appreciated.
I have a table named users which contains 4 columns
+---------+-----------+---------------+--------------+
| user_id | user_name | user_password | user_stopped |
+---------+-----------+---------------+--------------+
| 1 | admin | admin | false |
| 2 | user2 | 2 | false |
| 3 | user3 | 3 | true |
+---------+-----------+---------------+--------------+
I have a from with three textboxes "txtuserid" & "textusername" & "txtuserpassword" and a button name "login"
1) on the "on_click" event of the "login" button , I have this query
Dim query = From check In Me.MydatabaseDataSet.users
Where check.user_id = Me.txtuserid.Text
Select check.user_name, check.user_password, check.user_stopped
I want to do something like this:
if query.check.user_stopped= true then
msgbox("this user has no permission")
else
me.txtusername.text= query.user_name
if me.txtuserID.text= query.check.user_id and
me.txtuserpassword.text= query.check.user_password then
me.hide()
form2.show()
end if
end if
I have been trying for hours but nothing seems to work at all.
I'm using VB.net 2010 with SQL database.
All your help is highly appreciated.
In fact Linq is really simple.
Dim id as Integer
integer.TryParse(Me.txtuserid.Text, id)
Dim query = From check In Me.MydatabaseDataSet.users
Where check.user_id = id
Select check
Would simply return all users with a given Id (Me.txtuserid.Text - converted to integer, it is an integer, right?).
If you specifically want 3 columns:
Dim query = From check In Me.MydatabaseDataSet.users
Where check.user_id = id
Select New With {check.user_name, check.user_password, check.user_stopped}
But keep in mind, this version is returning anonymous type where previous one returns User type.
If you think about it, user_id is a primary key (unique). Thus you don't need to get back a "collection" as the above "query", you simply need a single User:
Dim user = Me.MydatabaseDataSet.users.SingleOrDefault(Function(check) check.user_id = id)
If that ID exists than the user has properties of that user (typed data), else NULL.
This one matches to code that you later want to execute:
if user is not nothing
msgbox("unknown user")
else
if user.user_stopped= true then
msgbox("this user has no permission")
else
me.txtusername.text= user.user_name
if me.txtuserID.text= user.user_id and
me.txtuserpassword.text= user.user_password then
me.hide()
form2.show()
end if
end if
end if
Note: I assume this is just for hobby testing purposes, in real world you would never want to store plain text passwords.
We have an access database create a csv list in an access table for each userid that logs into a computer. The problem is that if a userid logs in multiple times on one computer, than the userid is duplicated.
SO let's say this is what the table structure looks like
computer DailyUsers
ABC-123 ml12, rs12, ml12, ml12, ee13
DEF-456 zx44, aa33, zx44
And this is what I want a query to return
Computer DailyUsers
ABC-123 ml12, rs12, ee13
DEF-456 zx44, aa33
I tried using both Group By and Distinct but that looks on a row by row basis, not a field basis
How can this be achieved in Access 2013?
You can create a custom function in VBA to return only the unique users.
Add this in a VBA module:
Option Compare Database
Option Explicit
Public Function DistinctOnly(txt As String)
Dim arr, v, rv As String
Dim d As Object
arr = Split(txt, ",")
If UBound(arr) > 0 Then
Set d = CreateObject("scripting.dictionary")
For Each v In arr
d(Trim(v)) = 1
Next v
rv = Join(d.keys, ",")
Else
rv = txt
End If
DistinctOnly = rv
End Function
Usage:
SELECT Table1.[ID], Table1.[Users], DistinctOnly(Table1.[Users]) as UsersX
FROM Table1;
Input data and query results:
I m new to vb net
So here is my problem
My database has 1 table=quiz and 3 columns of ID ,name and Flag
All flags are set to '0'
Whenever I delete ,instead of deleting ,I update the name field to xxx and Flag to 1
In my database ,ID =3 has name = xxx
Still y is it entering the loop? and printing the msg"OH no"?
my code :
Dim SQL as String
SQL = "SELECT Name FROM quiz WHERE Flag='0' AND ID='3'"
c = 0
If SQL <> "xxx"Then
' Try, Catch, Finally
i = i + 1
MsgBox("Ohh no")
END IF