Installment system with invoice dividing in VB.NET - vb.net

I'm fighting with something for a couple of days and I really need help from You because it's too difficult for me.
There are many debtor customers of the company I work in. Sometimes they cannot pay off all debt so they would like to pay off their arrears in installment/loan system. I'm working on it using VB.NET. I have to prepare the shedule which will divide every installment for individual invoices. I could easily split invoices to installments with payment deadlines for each one, but after that, in the second step, I have to divide each installment on invoices. There is an example of this accounting made manually in Excel for 2 exemplary invoices below. I know that loops used in the code should have 2 "if" conditions: Condition1: Installment amonunt < Invoice amount and Condition2: Installment amonunt >= Invoice amount, but app user (employee of the debt collection department) can generate mixed shedule (various amounts of each installment) where both of condition can be met.
Additionally the simplification is that the program will not charge interest at all (higher level[! decision).
I'll be very thankful for any help or any clue to solve this problem.
Maybe some of You have had such a problem before 🙂
Thanks in advance!

For accounting application, we have a matching table to bridge between the invoice and receipt(Instalment). When an instalment is scheduled, you match to the invoice accordingly base on FIFO. So you need to update the data to the matching table and at the same time you need to have a Amount Match and Amountunmatched field on you invoice to keep track of the partial payment.
so when the first schedule is done
Instalment : Inst 1
Invoice : Inv A
Amtmatched : 50
MatchDate : 2021-05-15
Debtor : ABC
At the same time you need update the Invoice A amountmatched to 50 and amountunmatched to 106.53 (outstanding)
2nd Instalement
Instalment : Inst 2
Invoice : Inv A
Amtmatched : 50
MatchDate : 2021-06-15
Debtor : ABC
3rd Instalement
Instalment : Inst 3
Invoice : Inv A
Amtmatched : 50
MatchDate : 2021-07-15
Debtor : ABC
4th Instalement, you need to update 2 records
Instalment : Inst 4
Invoice : Inv A
Amtmatched : 6.53
MatchDate : 2021-08-15
Debtor : ABC
Instalment : Inst 4
Invoice : Inv B
Amtmatched : 43.47
MatchDate : 2021-08-15
Debtor : ABC
You can see this patter is very similar to your table.
On the programming part, you need a date input of startdate, and number of instalment to work the amount for each instalment and the last instalment. You can use the oustanding divide by the outstanding and round it off and get the round off figure allocate to the last month.
Save the instalment schedule to a table first. After that loop the instalment schedule and generate the matching table and update the invoice outstanding for each loop. If you think this method can do the trick and you need further help. You just buzz me.

This is the database diagram and some data sample
This is the program UI
I will put in the number of instalment I want to schedule and Instalment prefix to generate the transaction no for the instalment.
Here goes the code
Imports System.Data.SqlClient
Public Class frmInstalment
Private Sub btnGenerateInstalment_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGenerateInstalment.Click
Dim TotalOustanding = Modws.GetDecimalFromQuery("Select Sum(amtunmatched) from Invoice")
Dim InstNo As Integer = Val(txtInstalmentNo.Text)
Dim Balance = TotalOustanding
Dim i As Integer = 1
Do Until i = InstNo + 1
Dim InstalAmount = Math.Ceiling(TotalOustanding / InstNo)
Balance = Balance - InstalAmount
Dim Amount As Decimal
If Balance > 0 Then
Amount = InstalAmount
Else
Amount = InstalAmount + Balance
End If
Dim InstalNo As String = txtInsalPre.Text & i.ToString("00")
Modws.UpdateItem("Insert into Instalment(TransNo,Instalment,Amount) Values('" & InstalNo & "'," & i & ", " & Amount & ")")
i = i + 1
Loop
Modws.DisplayDataGrid(dgvInstalment, "Select TransNo,Instalment,Amount from Instalment Order by TransNo")
For x = 0 To dgvInstalment.Rows.Count - 1
AddMatching(dgvInstalment("TransNo", x).Value, Val(dgvInstalment("Amount", x).Value))
Next
Modws.DisplayDataGrid(dgvResult, "Select * from Matching Order by Instalment")
End Sub
Private Sub AddMatching(InstalmentNo As String, InstAmt As Decimal)
Dim StrConn As String = My.Settings.ImportLinkCS
Dim CN = New SqlConnection(StrConn)
CN.Open()
Dim StrSql As String = "Select * from Invoice Where AMTUNMATCHED <> 0 order by transdate, TransNo"
Dim cmdReader As SqlCommand = New SqlCommand(StrSql, CN)
cmdReader.CommandType = CommandType.Text
Dim SdrReader As SqlDataReader = cmdReader.ExecuteReader(CommandBehavior.CloseConnection)
'SdrReader = cmdReader.ExecuteReader
Try
With SdrReader
If .HasRows Then
While .Read
If .Item("Amtunmatched") > InstAmt Then
Modws.UpdateItem("Update Invoice set amtmatched = amtmatched + " & InstAmt & ",amtunmatched = amtunmatched - " & InstAmt & " Where TransNo = '" & .Item("TransNo") & "'")
Modws.UpdateItem("Insert into Matching(Invoice,Instalment,Amtmached,InvOutstanding) " + _
"Values('" & .Item("TransNo") & "','" & InstalmentNo & "', " & InstAmt & "," & (.Item("Amtunmatched") - InstAmt) & " )")
Exit Sub
Else
Modws.UpdateItem("Update Invoice set amtmatched = Total,amtunmatched = 0 Where TransNo = '" & .Item("TransNo") & "'")
Modws.UpdateItem("Insert into Matching(Invoice,Instalment,Amtmached,InvOutstanding) " + _
"Values('" & .Item("TransNo") & "','" & InstalmentNo & "'," & .Item("AMTUNMATCHED") & ",0 )")
InstAmt = InstAmt - .Item("Amtunmatched")
End If
End While
End If
End With
Catch ex As System.Exception
MsgBox(ex.Message, MsgBoxStyle.Critical, "Error")
End Try
End Sub
Private Sub btnReset_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReset.Click
Modws.DeleteItem("Delete from Instalment")
Modws.DeleteItem("Delete from Matching")
Modws.UpdateItem("Update Invoice set amtmatched = 0, amtunmatched = Total")
End Sub
End Class
You also need to add a module class in your program
Imports System.Data
Imports System.Data.SqlClient
Imports ImportLink.GridPrintPreviewLib
Module Modws
Public Function GetDecimalFromQuery(ByVal SQLQuery As String) As Decimal
Dim StrConn As String = My.Settings.ImportLinkCS
Dim CN = New SqlConnection(StrConn)
GetDecimalFromQuery = 0
CN.Open()
Dim StrSql As String = SQLQuery
Dim cmdReader As SqlCommand = New SqlCommand(StrSql, CN)
cmdReader.CommandType = CommandType.Text
Dim SdrReader As SqlDataReader = cmdReader.ExecuteReader(CommandBehavior.CloseConnection)
'SdrReader = cmdReader.ExecuteReader
'GetDoubleFromQuery = 0
Try
With SdrReader
If .HasRows Then
While .Read
If .GetValue(0) Is DBNull.Value Then
'GetDoubleFromQuery = 20
'MsgBox("Null Value")
Else
If IsDBNull(.GetValue(0).ToString) Then
'GetDoubleFromQuery = 50
'MsgBox("Null Value")
Else
GetDecimalFromQuery = .GetValue(0).ToString
End If
End If
End While
Else
'MsgBox("No Row")
End If
End With
CN.Close()
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Exclamation, "Error")
End Try
End Function
Public Sub UpdateItem(ByVal SqlQuery As String)
Dim StrConn As String = My.Settings.ImportLinkCS
Dim CN = New SqlConnection(StrConn)
Try
CN.Open()
Dim StrSql As String = SqlQuery
Dim cmdupdate As New SqlCommand(StrSql, CN)
cmdupdate.CommandText = StrSql
cmdupdate.ExecuteNonQuery()
Catch ex As Exception
MsgBox(ex.Message & SqlQuery, MsgBoxStyle.Exclamation, "Error-UpdateItem")
End Try
CN.Close()
CN = Nothing
End Sub
Public Sub DisplayDataGrid(ByVal dgv As DataGridView, ByVal SQLSTR As String)
dgv.DataSource = Nothing
Try
Dim dbBindSource As New BindingSource
Dim strCon As String = My.Settings.ImportLinkCS
Dim strSQL As String = SQLSTR
Dim dataAdapter As SqlDataAdapter = New SqlDataAdapter(strSQL, strCon)
Dim commandBuilder As SqlCommandBuilder = New SqlCommandBuilder(dataAdapter)
'Populate a new data table and bind it to the BindingSource.
Dim table As DataTable = New DataTable()
table.Locale = System.Globalization.CultureInfo.InvariantCulture
dataAdapter.Fill(table)
dbBindSource.DataSource = table
'Resize the DataGridView columns to fit the newly loaded content.
dgv.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader)
dgv.DataSource = dbBindSource
dgv.Columns(2).Width = 200
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical, "error")
End Try
End Sub
End Module
And This is the result I'm getting
I have tried and it is working fine. In addition, you just need to add customer parameter so that it will process base on the customer.

Related

How come my code works when stepping through it, but doesn't when it's running normaly?

I am making an EPOS system for a school project, everything works fine, except one thing. The code does not work more than once when running properly, however, when I step through it line by line it works without any problems. The code takes a barcode inputted into a textbox, queries the products table to find the name of the product. It then takes the date and the barcode makes a composite key to check if there has been a previous sale of that product in that day, by querying the sales table. If the entry is new it creates a new line in the database, if the entry is new it queries the sales table for the quantity, adds one to it and updates that row with the quantity +1. Any ideas to why this might be happening is greately appreciated. Here is the relevant code:
Sub txtBarcode_KeyDown(sender As Object, e As KeyEventArgs) Handles
txtBarcode.KeyDown
If e.KeyCode = Keys.Enter Then
BarcodeProcess()
end if
End Sub
Sub BarcodeProcess()
Dim barcode As String
barcode = txtBarcode.Text
SoldItems(barcode)
txtBarcode.Clear()
txtBarcode.Select()
txtBarcode.Update()
End Sub
Function SoldItems(ByRef barcode As String) 'This function takes the
barcode and makes a record in the database with the product name, amount
sold and date sold
con.Close()
con.Open()
Dim thedate As String = String.Format("{0:dd/MM/yyyy}", DateTime.Now)
'Sets the date in the format day/month/year e.g. 01/02/2019
Dim ProductBought As String = FindItem(barcode)
'Returns the name of the the item sold
Dim quantity As integer
Dim test As New OleDbCommand("SELECT Product_Name FROM Sales WHERE
ProductID_DateSold ='" & barcode & thedate & "'", con)
Dim numberof As New OleDbCommand("SELECT Quantity_Sold FROM Sales
WHERE ProductID_DateSold ='" & barcode & thedate & "'", con)
If test.ExecuteScalar = ProductBought Then
'If the same product has been bought more than once in the same day
'then the number of items sold increases by 1
quantity = numberof.executescalar
quantity += 1
Dim update As New OleDbCommand("UPDATE Sales SET Quantity_Sold ="
& quantity & " WHERE ProductID_DateSold ='" & barcode & thedate &
"'", con)
update.ExecuteNonQuery
Else
'If it is the first time the product is bought that day a new row is
'inserted into the database
Dim insert As New OleDbCommand("INSERT INTO Sales
(Product_ID,Product_Name,Date_Sold,Quantity_Sold,
ProductID_DateSold) VALUES ('" & barcode & "','" & ProductBought
& "','" & thedate & "'," & quantity + 1 & ",'" & barcode &
thedate & "')", con)
Try
insert.ExecuteNonQuery
Catch ex As Exception
Errors(ex.message)
End Try
End If
OutputBox.Items.Insert(0, "One " & ProductBought & " has been sold.")
OutputBox.Update()
con.Close()
Return nothing
End Function
Function FindItem(byVal barcode As String)
con.Close()
Dim name As String
Dim da As New OleDb.OleDbCommand("SELECT Product_Name FROM Products WHERE ProductID = '" & barcode & "'", con)
Try
con.Open()
name = da.ExecuteScalar
Catch ex As Exception
End Try
Return name
End Function

Data return is NULL even tho I have a value on my SQL in VB.NET

Good day this is the continuation on my previous question since it's already been solved.
Issue with Custom Date Format in VB.NET
Now the problem is WHEN I test my SQL query in phpMyAdmin returned a value
it means that the rd.GetString(0) has a value of "3"
But when the vb.net load the value, it will return an error:
Additional information: Data is Null. This method or property cannot be called on Null values.
Why is the Data is NULL but on my SQL screenshot is working fine?
this is the error that refer to
If Convert.ToDouble(rd.GetString(0)) >= 80.0 Then
or I use this
If rd.GetDecimal(0) >= 80.0 Then
same result
My entire code:
Dim startDayMonth As DateTime = FirstDayOfMonth(Now).AddHours(6)
Dim lastDayMonth As DateTime = LastDayOfMonth(Now).AddHours(22)
Dim qry As String = "SELECT SUM(totalWorkHour) as totalWorkHour FROM tbltimesheet WHERE studInfoID=#id " _
& "AND timeIn BETWEEN #checkAM AND #checkPM"
Using con As New MySqlConnection("server=192.168.*.***; user=dummyUsername; password=dummyPasswrd; database=dummyDBName;"), _
cmd As New MySqlCommand(qry, con)
cmd.Parameters.Add("#id", MySqlDbType.Int32).Value = Convert.ToInt32(Me.txtStudID.Text)
cmd.Parameters.Add("#checkAM", MySqlDbType.DateTime).Value = startDayMonth
cmd.Parameters.Add("#checkPM", MySqlDbType.DateTime).Value = lastDayMonth
con.Open()
Using rd As MySqlDataReader = cmd.ExecuteReader()
'Better practice here would be to return the value (if any) from this function
If rd.Read() Then
If rd.GetDecimal(0) >= 80.0 Then
MsgBox("Hurray! You already reach your target: " & rd.GetString(0), MsgBoxStyle.Information, Title:="Result")
Else
MsgBox("Your Total Work Hour: " & rd.GetString(0), MsgBoxStyle.Information, Title:="Result")
End If
Else
MsgBox("No Record Found", MsgBoxStyle.Critical, Title:="Error")
End If
End Using
End Using
rd.Close()
con.Close()
Lots of small fixes in here:
'Just leave these as a datetime
Dim StartDayMonth As DateTime = FirstDayOfMonth(Now).AddHours(6)
Dim LastDayMonth As DateTime = LastDayOfMonth(Now).AddHours(22)
Dim qry As String = _
"SELECT SUM(totalWorkHour) as totalWorkHour " & _
" FROM tbltimesheet " & _
" WHERE studInfoID=#id AND timeIn BETWEEN #checkAM AND #checkPM"
'.Net uses Connection Pooling for database objects...
' This means create a new connection for every query in most cases
' but limit the scope and duration of the connection as much as possible
' (wait until the last possible moment to call .Open())
Using con As New MySqlConnection("connection string here"), _
cmd As New MySqlCommand(qry, con)
cmd.Parameters.Add("#id", MySqlDbType.Int32).Value = Convert.ToInt32(Me.txtStudID.Text)
cmd.Parameters.Add("#checkAM", MySqlDbType.DateTime).Value = StartDayMonth
cmd.Parameters.Add("#checkPM", MySqlDbType.DateTime).Value = LastDayMonth
con.Open()
Using rd As MySqlDataReader = cmd.ExecuteReader()
'Better practice here would be to return the value (if any) from this function
If rd.Read()
Dim hours As Double = rd.GetDouble(0)
If hours >= 80.0 Then
MsgBox("Hurray! You already reach your target: " & hours.ToString(), MsgBoxStyle.Information, Title:="Result")
Else
MsgBox("Your Total Work Hour: " & hours.ToString(), MsgBoxStyle.Information, Title:="Result")
End If
Else
MsgBox("No Record Found", MsgBoxStyle.Critical, Title:="Error")
End If
End Using
End Using
Now that I can also see the module, you want code more like this:
Module db
'Note that this is PRIVATE
' Goal is to make sure any db access in your code really
' does use the interface provided by your db module.
Private ConnectionString As String = "server=192.168.*.***; user=******; password=*****; database=dbsalog;"
'Note the use of types here in the function definition.
'Also note how I separate concerns here:
' Limit functions in this Module to just database access doing database things
' Let your presentation code in your form worry about MsgBox() and other concerns
Public Function GetWorkHours(StudentId As Integer) As Double
Dim StartDayMonth As DateTime = FirstDayOfMonth(Now).AddHours(6)
Dim LastDayMonth As DateTime = LastDayOfMonth(Now).AddHours(22)
Dim qry As String = _
"SELECT SUM(totalWorkHour) as totalWorkHour " & _
" FROM tbltimesheet " & _
" WHERE studInfoID=#id AND timeIn BETWEEN #checkAM AND #checkPM"
Using con As New MySqlConnection(ConnectionString), _
cmd As New MySqlCommand(qry, con)
cmd.Parameters.Add("#id", MySqlDbType.Int32).Value = StudentId
cmd.Parameters.Add("#checkAM", MySqlDbType.DateTime).Value = StartDayMonth
cmd.Parameters.Add("#checkPM", MySqlDbType.DateTime).Value = LastDayMonth
con.Open()
Using rd As MySqlDataReader = cmd.ExecuteReader()
If rd.Read() Return rd.GetDouble(0)
End Using
End Using
Return Nothing
End Function
End Module
Which you can call from a form or other area of your program like this:
Dim workHours As Double = db.GetWorkHours(Convert.ToInt32(Me.txtStudId.Text))
If workHours = Nothing Then
MsgBox("No Record Found", MsgBoxStyle.Critical, Title:="Error")
ElseIf workHours >= 80.0 Then
MsgBox("Hurray! You already reach your target: " & workHours.ToString(), MsgBoxStyle.Information, Title:="Result")
Else
MsgBox("Your Total Work Hour: " & workHours.ToString(), MsgBoxStyle.Information, Title:="Result")
End If

How to know the available time and date in Reservation/CheckIn Program

I am using Visual Basic.Net and I have a problem in knowing the available Date, Time, and Room for the reservation/checkin of Hotel/Resort Reservation Program. Here in this code provided below, when I tried to reserve the specific room in a specific date and time, then restart the program, when I tried to save again with the unavailable room/date/time, the program's condition has wrongly allowed to save it again with the conflict schedule. I am using visual basic. Thank you :)
Dim varConflictSched As Boolean = False
Dim dsCheckIn As New DataSet
Dim daCheckIn As OdbcDataAdapter = New OdbcDataAdapter("SELECT * FROM tblCheckIn ORDER BY ID", MyConn)
daCheckIn.Fill(dsCheckIn, "tblCheckIn")
Dim DateTimeRangeNewIn(Val(Me.txtstaying.Text)) As DateTime
Dim DateCheckInNew As DateTime = Me.dtpCheckIn.Value
For a As Integer = 0 To dsCheckIn.Tables("tblCheckIn").Rows.Count - 1
Dim DateTimeRangeOldIn(dsCheckIn.Tables("tblCheckIn").Rows(a)("Staying")) As DateTime
REM Check if the room number is in used
If Me.cbRoomNumber.SelectedItem = dsCheckIn.Tables("tblCheckIn").Rows(a)("RoomNumber").ToString Then
REM Check if the date and time of the specified room number is in used
Dim varCheckInDate As DateTime = dsCheckIn.Tables("tblCheckIn").Rows(a)("CheckInDate")
For b As Integer = 0 To dsCheckIn.Tables("tblCheckIn").Rows(a)("Staying")
For c As Integer = 0 To Val(Me.txtstaying.Text)
DateTimeRangeOldIn(b) = varCheckInDate.AddDays(b)
DateTimeRangeNewIn(c) = DateCheckInNew.AddDays(c)
If DateTimeRangeOldIn(b).Date = DateTimeRangeNewIn(c).Date Then
If DateDiff(DateInterval.Minute, DateTimeRangeOldIn(b), DateTimeRangeNewIn(c)) <= 0 Then
varConflictSched = True
Exit For
End If
End If
Next
Next
End If
Next
If Me.txtAmount.Text = "" Or Me.txtSearch.Text = "" Or Me.txtstaying.Text = "" Or Me.txtTotal.Text = "" Or Me.cbRoomNumber.SelectedIndex = -1 Or Me.cbRoomtype.SelectedIndex = -1 Then
MessageBox.Show("Required field(s) should not be left blank" & vbCrLf & "Please try again", "NO BLANK SPACE", MessageBoxButtons.OK, MessageBoxIcon.Error)
ElseIf varConflictSched = True Then
MessageBox.Show("Can't set schedule with this date." & vbCrLf & "Please insert another date.", "CONFLICT", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
Dim DAdapter As OdbcDataAdapter = New OdbcDataAdapter("SELECT * FROM tblCheckIN ORDER BY ID ", MyConn)
Dim DSet As New DataSet
DAdapter.Fill(DSet, "tblCheckIN")
Dim NewID As Integer = DSet.Tables("tblCheckIN").Rows(DSet.Tables("tblCheckIN").Rows.Count - 1)("ID") + 1
Dim CommCheckIn As OdbcCommand = New OdbcCommand("INSERT INTO tblCheckIN (ID,CustomerID,Roomtype,RoomNumber,Amount,CheckInDate,Staying)VALUES(" & NewID & ",'" & Me.txtSearch.Text & "','" & Me.cbRoomtype.SelectedItem & "','" & Me.cbRoomNumber.SelectedItem & "','" & Me.txtAmount.Text & "','" & Me.dtpCheckIn.Value & "' , '" & Me.txtstaying.Text & "')", MyConn)
MyConn.Open()
CommCheckIn.ExecuteNonQuery()
MyConn.Close()
MessageBox.Show("Your Checking-In is succesfully saved. ", "SAVED", MessageBoxButtons.OK, MessageBoxIcon.Information)
Me.ClearAll()
End If
You don’t need looping code to find a collision.
A collision occurs when:
RequestionStartDate <= EndDate
And
RequestEndDate >= StartDate
Of course you have to add roomnumber to above, but it rather simple.
So on book button, your code will do this:
Dim strSQL As String
Dim rstData As New DataSet
Dim daRead As SqlDataAdapter
strSQL = "select * from tblCheckIn where RoomNumber = #RoomNum " & _
" AND ( (#CheckIn <= CheckOutDate) AND (#CheckOut >= CheckInDate) )"
Dim MySql As SqlCommand = New SqlCommand(strSQL, GetCon)
MySql.Parameters.Add("#RoomNum", SqlDbType.Int).Value = Me.RoomNumber.Value
MySql.Parameters.Add("#CheckIn", SqlDbType.DateTime).Value = Me.dtpCheckIn.Value
MySql.Parameters.Add("#CheckOut", SqlDbType.DateTime).Value = Me.dtpCheckOut.Value
daRead.SelectCommand = MySql
daRead.Fill(rstData)
If rstData.Tables(0).Rows.Count > 0 Then
MsgBox("you have a booking collsion")
End If
The above works since you never allow a collsion, and the above will return any record that you "over lap". this includes the cases like this:
RequestStart RequestEnd
| |
| exsiting Start/end |
or
RequestStart RequestEnd
| |
| exist Start Exist end |
or
RequestStart RequestEnd
| |
| exist Start Exist end |
in fact any combination of ANY overlap will be found by the above simple query.

Cannot open any more tables - OleDbException was unhandled

Good Day,
My question is how to handle the exception or get rid of the error pertaining to "Cannot open any more tables". For an overview to the program I was creating, I pull out the record of subject in ms access 2007, I loop to that record to randomly assign a schedule and one by one I insert the newly record with assigned schedule in the table.
My program flow of inserting the record work only for a certain number of times, like almost 200 and at some point it stop and pop-up the oledbexception
Thanks in advance for your time on answering my question.
here is my code for more detailed overview of my program,
Private Sub Assignsched(ByVal rType As String, ByVal subjectCode As String, ByVal SecID As String, ByVal CourseCode As String)
If shrdcon.con.State = ConnectionState.Closed Then
shrdcon.con.Open()
End If
Dim RoomNum As Integer
dtARoom.Clear()
Dim stoploop As Boolean
Dim count As Integer = 0
Dim rm1 As String
RoomAssign = ""
rm1 = "SELECT * FROM tblRoom WHERE RoomType = '" & rType & "'"
Dim dat As New OleDbDataAdapter(rm1, shrdcon.con)
dat.Fill(ds, "ARoom")
stoploop = False
count = 0
Do Until stoploop = "True"
RoomNum = rndm.Next(0, ds.Tables("ARoom").Rows.Count)
RoomAssign = ds.Tables("ARoom").Rows(RoomNum).Item(1)
ScheduleGeneration()
If checkExisting(sTime, eTime, RoomAssign, daypick) = False Then
RoomA = RoomAssign
GenerateOfferingID()
Dim cmd1 As New OleDbCommand()
cmd1.CommandText = "INSERT INTO [tblSubjectOffer]([SubjectOID],[SubjectCode],[SectionID],[Day],[sTime],[eTime],[RoomName],[CourseCode]) VALUES('" & _
myId & "','" & subjectCode & "','" & SecID & "','" & daypick & "'," & sTime & "," & eTime & ",'" & RoomA & "','" & CourseCode & "')"
cmd1.Connection = shrdcon.con
cmd1.ExecuteNonQuery()
cmd1.Dispose()
Dim pipz As New OleDbCommand("Update tblGenerator Set NextNo='" & myId & "' where TableName ='" & "tblSubjectOffer" & "'", shrdcon.con)
pipz.ExecuteNonQuery()
pipz.Dispose()
stoploop = True
Else
stoploop = False
End If
If stoploop = False Then
If count = 30 Then
stoploop = True
Else
count = count + 1
End If
End If
Loop
End Sub
This is typical error happens with Microsoft Jet engine when You have exceeded the maximum number of open TableIDs allowed by the Microsoft Jet database engine, which is 2048 with Jet3.5 engine and 1024 with older engines.
Even though you are closing the Command objects after each use, you are still using the same connection for the whole process, which actually holds the TableID's and is at some point of time exceeding the number of allowed open TableID's.
A probable solution would be to update the Jet Engine with the latest, which is available here
It might solve your problem, but if you are already using the latest engine, you have to look into other options to reduce the number of DB operations.
Try using the UpdateBatch method for applying the updates as a batch.
Hope this helps
Private Sub Command1_Click()
Dim myConnection As ADODB.Connection
Dim rsData As ADODB.Recordset
Set myConnection = New ADODB.Connection
myConnection.ConnectionString = "xxxxxxxxxxxxxxxxxxxx"
myConnection.Open
Set rsData = New ADODB.Recordset
rsData.CursorLocation = adUseClient
rsData.Open "select * from mytable", myConnection, adOpenStatic, adLockBatchOptimistic
For i = 1 To 10000
rsData.AddNew
rsData.Fields(0).Value = 1
rsData.Fields(1).Value = 2
Next i
rsData.UpdateBatch
rsData.Close
myConnection.Close
Set rsData = Nothing
End Sub
Good Evening,
Recently I encounter this type of error and i was able to resolve it by adding
con.close and call conState (a procedure conState- check below) before any insert/update or select statement
In my code i have something like
For i = 0 To DataGridView1.RowCount - 1
reg = DataGridView1.Rows(i).Cells(0).Value
Label2.Text = reg
'i added this two lines
***con.Close()***
***Call conState()***
Dim cmdcheck As New OleDbCommand("Select * from [2015/2016 UG CRF] where regno ='" & reg & "'", con)
Dim drcheck As OleDbDataReader
drcheck = cmdcheck.ExecuteReader
If drcheck.Read = True Then
GoTo A
End If
coursesFirst = String.Empty
coursesSecond = String.Empty
creditFirst = 0
creditSecond = 0
Dim cmdlevel As New OleDbCommand("Select * from [2015/2016 UG registration Biodata 5 april 16] where regno ='" & reg & "'", con)
Dim drlevel As OleDbDataReader
drlevel = cmdlevel.ExecuteReader
If drlevel.Read = True Then
level = drlevel.Item("level").ToString
faculty = drlevel.Item("faculty").ToString
program = drlevel.Item("programme").ToString
End If
...............
next
The conState is a connection testing if connection is closed is should open it again like in below
Public Sub conState()
If con.State = ConnectionState.Closed Then
con.Open()
End If
End Sub
This stop the error message
I got this exception in my C# application and the cause was using OleDbDataReader instances without closing them:
OleDbDataReader reader = cmd.ExecuteReader();
bool result = reader.Read();
reader.Close(); // <= Problem went away after adding this
return result;

Sql statement returning incorrect data

I am confused as to why my SQL select statement is returning incorrect data. In my database the value is 009698 and it is returning 9698. Could someone shed some light as to why this would be happening.
It is an MS Access 2010 database and the column is text and the size is 6.
Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
Try
DBConnection.connect()
sql = "SELECT MAX([Request no]) from Requests WHERE Customer = '" & cmbCustomer.Text & "' "
Dim cmd As New OleDb.OleDbCommand
Dim id As Integer
cmd.CommandText = sql
cmd.Connection = oledbCnn
dr = cmd.ExecuteReader
While dr.Read()
id = CInt(dr.Item(0))
id = (id) + 1
End While
'MessageBox.Show("00" & id)
'sql = "INSERT INTO Requests ([Request no], Customer) VALUES ('" & id & "', '" & cmbCustomer.Text & "')"
cmd.Dispose()
'dr.Close()
oledbCnn.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
You are treating the returned value as integer so '009698' and '9698' are the same values in this context.
If you want to later convert it to a six-digit string, you can do:
Dim stringId as String
While dr.Read()
id = CInt(dr.Item(0))
id = (id) + 1
stringId = id.ToString().PadLeft(6, "0"c)
End While
Since the field is text, why not use the GetString function on the DataReader.
Dim id As String
While dr.Read
''The string value returned from the database
Dim stringID = dr.GetString(0)
''convert the string to an int and add 1
Dim numericID = CInt(stringID) + 1
''convert the number back to a string with leading 0
id = numericID.ToString.PadLeft(stringID.Length, "0")
End While
I'm assuming you're trying to get the string value from a db, convert it to a number, add one, and then convert it back to the string format with leading zeros.