Update data based on serial number - excel

I have a UserForm that enables users to enter data into a worksheet.
A serial number is created for each row of data based on 2 ComboBox selection and 0001 at the end.
For example, MAPR0001 where MA comes from a ComboBox and PR from another one and at the end 0001 is added and is incremented for another selection of MA and PR. (MAPR0002)
Then I have a second UserForm that should allow me to update my database.
Upon selection of a serial number from a ComboBox the second UserForm pulls back the data from the worksheet to some TextBoxes.
Till here everything works fine.
But I fail to add data to a specific serial number.
My code for the command button:
Private sub Commandbuttonclick ()
If Me.ComboBox1.Value = "" Then
MsgBox "Request No. Can Not be Blank", vbExclamation, "Request No."
Exit Sub
End If
requestno = Me.ComboBox1.Value
Sheets("DASHBOARD").Select
Dim rowselect As Double
rowselect = Me.combobox1.Value
rowselect = rowselect + 1
Rows(rowselect).Select
Cells(rowselect, 2) = Me.TextBox1.Value
Cells(rowselect, 3) = Me.TextBox2.Value
Cells(rowselect, 4) = Me.TextBox3.Value

Use the WorksheetFunction.Match method to find your serial number that you want to update. Match returns the row number that you could use instead of rowselect to write your data.
For example something like this:
Dim MySerial As String
MySerial = "MAPR0001" 'adjust to your needs
Dim MyLookupRange As Range
Set MyLookupRange = Sheets("DASHBOARD").Range("A:A") 'adjust to where your serials are
Dim RowToUpdate As Long
On Error Resume Next 'next line throws error if serial not found
RowToUpdate = WorksheetFunction.Match(MySerial, MyLookupRange, 0)
On Error Goto 0 'always re-enable error reporting!
If RowToUpdate > 0 Then
'serial found, update here eg …
'Sheets("DASHBOARD").Cells(RowToUpdate, 2) = Me.TextBox1.Value
Else
MsgBox "Serial " & MySerial & " was not found."
End If

There are a few ways to do this. Here is one option for you to try.
'Private Sub Worksheet_Change(ByVal Target As Range)
Sub ImportDataFromExcel()
Dim rng As Range
Dim r As Long
Dim conn As ADODB.Connection
Dim strConn As String
Dim strSQL As String
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _
"C:\Users\Ryan\Desktop\Coding\Integrating Access and Excel and SQL Server\Access & Excel & SQL Server\" & _
"EXCEL AND ACCESS AND SQL SERVER\Excel & Access\Select, Insert, Update & Delete\Northwind.mdb"
Set conn = New ADODB.Connection
conn.Open strConn
With Worksheets("Sheet1")
lastrow = .Range("A2").End(xlDown).Row
lastcolumn = .Range("A2").End(xlToRight).Column
Set rng = .Range(.Cells(lastrow, 1), .Cells(lastrow, lastcolumn))
End With
'therow = 1
For i = 2 To lastrow
'r = rng.Row
'If r > 1 Then
strSQL = "UPDATE PersonInformation SET " & _
"FName='" & Worksheets("Sheet1").Range("B" & i).Value & "', " & _
"LName='" & Worksheets("Sheet1").Range("C" & i).Value & "', " & _
"Address='" & Worksheets("Sheet1").Range("D" & i).Value & "', " & _
"Age=" & Worksheets("Sheet1").Range("E" & i).Value & " WHERE " & _
"ID=" & Worksheets("Sheet1").Range("A" & i).Value
conn.Execute strSQL
'End If
'r = r + 1
Next i
conn.Close
Set conn = Nothing
End Sub
This is for illustration purposes only. Please change to suit your specific needs.

Related

Having issues with pop-up alert in excel. (Visual Basic)

I tried to set up a code to have a message alert pop-up when a reagent is expiring in 7 days and when the reagent is expired, when the workbook opens. The message should include the reagent that is expired. I only attempted to have the code work for the 'FA Reagents' (A4:A20) and those reagents expiration dates (C4:C20), but I eventually would like to have the code work for all the reagents in this sheet.
Excel Sheet
Private Sub Workbook_Open()
Dim ws As Worksheet
Dim rReagents As Range
Set rReagents = Range("A4:A20")
Dim rExpiration As Range
Set rExpiration = Range("C4:C20")
Dim lLastrow As Long, i As Long
Set ws = Worksheets("Reagent-Equipment")
lLastrow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
With ws
For i = 2 To lLastrow
If .Cells(i, 2) = Date + 7 Then MsgBox ("Reagent expiring in 7 days for " & .Cells(i, 1))
If .Cells(i, 2) = Date Then MsgBox ("Reagent expiring today for " & .Cells(i, 1))
Next
End With
End Sub
This is the code I tried, but I can't a notification to pop-up when the workbook opens when a reagent is expired, or expired within 7 days.
You may find the following code of interest
Private Sub Workbook_Open()
Dim myShortDate As String
Dim myExpired As String
Dim ws As Worksheet
Set ws = Worksheets("Reagent-Equipment")
Dim myReagents As Variant
myReagents = Application.WorksheetFunction.Transpose(ws.Range("A4:A20").Value)
Dim myExpiry As Variant
myExpiry = Application.WorksheetFunction.Transpose(ws.Range("C4:C20").Value)
Dim myIndex As Long
myIndex = 1
Dim myItem As Variant
For Each myItem In myReagents
If Now > VBA.CDate(myExpiry(myIndex)) Then
If VBA.Len(myExpired) = 0 Then
myExpired = vbTab & myReagents(myIndex)
Else
myExpired = myExpired & vbCrLf & vbTab & myReagents(myIndex)
End If
ElseIf Now + 7 > VBA.CDate(myExpiry(myIndex)) Then
If VBA.Len(myShortDate) = 0 Then
myShortDate = vbTab & myReagents(myIndex) & " on " & myExpiry(myIndex)
Else
myShortDate = myShortDate & vbCrLf & vbTab & myReagents(myIndex) & " on " & myExpiry(myIndex)
End If
End If
myIndex = myIndex + 1
Next
If VBA.Len(myExpired) > 0 Then
myExpired = "Expired Reagents" & vbCrLf & vbCrLf & myExpired & vbCrLf & vbCrLf
End If
If VBA.Len(myShortDate) > 0 Then
myShortDate = "Reagents due to expire " & vbCrLf & vbCrLf & myShortDate & vbCrLf & vbCrLf
End If
Dim myMessage As String
myMessage = myExpired & myShortDate
If VBA.Len(myMessage) > 0 Then
MsgBox myMessage, vbCritical
End If
End Sub

How can I disable the change log sub that I have written by checking a check box?

I have written the below code in excel vba to log changes made in sheets to the change log sheet. I want to disable that sub if a check box is checked.
This code works perfectly for what I need it to do, just need to figure out a sub that does not allow this to run if a box is checked so every change is not being logged when necessary.
'declare global variable
Dim oldValue As String
Dim oldAddress As String
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
'declare variables for individual sheets
Dim sheet1 As String
NSWCCDFY22M = "Sheet 1"
Dim sheet2 As String
NSWCCDFY23M = "Sheet 2"
Dim sheet3As String
NSWCCDLSW = "Sheet 3"
'Logs change for any sheet that isnt the log itself (address, values, user, date/time, hyperlink, note)
If ActiveSheet.Name <> "ChangeLog" Then
Application.EnableEvents = False
Sheets("ChangeLog").Range("A" & Rows.Count).End(xlUp).Offset(1, 0).Value = ActiveSheet.Name & " – " & Target.Address(0, 0)
Sheets("ChangeLog").Range("A" & Rows.Count).End(xlUp).Offset(0, 1).Value = oldValue
Sheets("ChangeLog").Range("A" & Rows.Count).End(xlUp).Offset(0, 2).Value = Target.Value
Sheets("ChangeLog").Range("A" & Rows.Count).End(xlUp).Offset(0, 3).Value = Environ("username")
Sheets("ChangeLog").Range("A" & Rows.Count).End(xlUp).Offset(0, 4).Value = Now
'hyperlink to specific sheet
If ActiveSheet.Name = Sheet 1 Then
Sheets("ChangeLog").Hyperlinks.Add Anchor:=Sheets("ChangeLog").Range("A" & Rows.Count).End(xlUp).Offset(0, 5), Address:="", SubAddress:="'" & Sheet 1 & "'!" & oldAddress, TextToDisplay:=oldAddress
ElseIf ActiveSheet.Name = Sheet 2 Then
Sheets("ChangeLog").Hyperlinks.Add Anchor:=Sheets("ChangeLog").Range("A" & Rows.Count).End(xlUp).Offset(0, 5), Address:="", SubAddress:="'" & Sheet 2 & "'!" & oldAddress, TextToDisplay:=oldAddress
ElseIf ActiveSheet.Name = Sheet 3 Then
Sheets("ChangeLog").Hyperlinks.Add Anchor:=Sheets("ChangeLog").Range("A" & Rows.Count).End(xlUp).Offset(0, 5), Address:="", SubAddress:="'" & Sheet 3 & "'!" & oldAddress, TextToDisplay:=oldAddress
End If
'input box for note
Dim commentChange As String
commentChange = InputBox("Please enter a note for this change.", "Logging")
Sheets("ChangeLog").Range("A" & Rows.Count).End(xlUp).Offset(0, 6).Value = commentChange
'if input box is not filled in
If LenB(commentChange) = 0 Then
MsgBox "You must enter a note for the change you've just made." & vbCrLf & " " & vbCrLf & "You will be taken to the Change Log to add a note and can navigate back to this sheet using the link associated with your change.", vbExclamation, "Change Log Required Actions"
Sheets("ChangeLog").Select
'go to log if a note is not put in
Dim lRow As Long
Dim lColumn As Long
lRow = Range("A1").End(xlDown).Row
lColumn = Range("A1").End(xlToRight).Column
Cells(lRow, lColumn).Select
Dim OutPut As Integer
'infobox when taken to log
OutPut = MsgBox("1. Please enter a note for the change you've just made." & vbCrLf & " " & vbCrLf & "2. Click the link in the 'Link' Column to return to the previous sheet where the change was made.", vbInformation, "Change Log Required Actions")
End If
Sheets("ChangeLog").Columns("A:G").AutoFit
Application.EnableEvents = True
End If
End Sub
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
If Target.Count = 1 Then
oldValue = Target.Value
End If
oldAddress = Target.Address
End Sub

Excel data to Access DB - Get: Operation must use an updateable query Error

I am working on an Excel application which allows users to enter hours work through userforms and info is stored in a Access DB. I am new to excel and access connections. I am able to connect to the database but record is not saved/created due to a run-time error at the .Update command.
Run-Time Error '-2147467259 (80004005)': Operation must use an updatable query.
I have searched and searched and can't find a solution to this problem. I hope someone is able to help. (code below)
Sub Export_Data_Access_TI1()
Dim dbPath As String
Dim x As Long, i As Long
Dim nextrow As Long
Dim user As String
Dim NewSht As Worksheet
Dim strQuery As String
Dim recDate As String
Dim Week_Of As String
user = Sheet1.Range("A1").Text
On Error GoTo ErrHandler:
'Variables for file path and last row of data
dbPath = "H:\PROJECTS\CAI_DOT-Time Tracker\CAI_EMP_SignIn_Database.accdb"
nextrow = Cells(Rows.Count, 1).End(xlUp).Row
'Initialise the collection class variable
Set cnn = New ADODB.Connection
'Check for data
If Sheets(user).Range("A2").Value = "" Then
MsgBox " There is no data to send to MS Access"
Exit Sub
End If
cnn.Mode = adModeReadWrite
'cnn.Mode = adModeShareDenyNone
cnn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPath
Set rst = New ADODB.Recordset 'assign memory to the recordset
rst.CursorLocation = adUseClient
rst.Open Source:="DATA", ActiveConnection:=cnn, _
CursorType:=adOpenKeyset, LockType:=adLockPessimistic, _
Options:=adCmdTable
'rst.Supports (adAddNew)
x = 2 'the start row in the worksheet
Do While Len(Sheets(user).Range("A" & x).Formula) > 0
With rst
.AddNew 'create a new record
.Fields("Date") = ActiveWorkbook.Sheets(user).Range("A" & x).Value
.Fields("Week_Of") = Sheets(user).Range("B" & x).Value
.Fields("Month") = Sheets(user).Range("C" & x).Value
.Fields("Name") = Sheets(user).Range("D" & x).Value
.Fields("Time_In") = Sheets(user).Range("E" & x).Value
.Fields("Time_Out") = Sheets(user).Range("F" & x).Value
.Fields("Time_In2") = Sheets(user).Range("G" & x).Value
.Fields("Time_Out2") = Sheets(user).Range("H" & x).Value
.Fields("Group") = Sheets(user).Range("I" & x).Value
.Fields("UniqueID") = Sheets(user).Range("J" & x).Value
.Fields("Comments") = Sheets(user).Range("K" & x).Value
.Update 'stores the new record
End With
x = x + 1 'next row
Loop
rst.Close
cnn.Close
Set rst = Nothing
Set cnn = Nothing
'communicate with the user
MsgBox " The data has been successfully sent to the access database"
'Update the sheet
Application.ScreenUpdating = True
'Clear the data
'Sheets(user).Range("A1:K1000").ClearContents
On Error GoTo 0
Exit Sub
ErrHandler:
'clear memory
Set rst = Nothing
Set cnn = Nothing
MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure Export_Data"
End Sub
As I understand, DATA is a query in the remote accdb. If so, it should be updateable. See, for example this: Why is my query not updateable? for criterias. If this is a table, check if you have read-write rights on accdb and the file has no read-only attribute.

Type mismatch error on VBA with empty cells which contain formulas

I am exporting data from Excel to Access. The data in Excel contains formulas, which are leaving cells blanks with if function: =IF(SISESTUS!B18="";"";SISESTUS!C18.
Problem is: VBA is not capable of reading blank cells with formulas. This raises a type mismatch error. When I copy only values then is ok, my export macro runs perfectly.
Code:
Sub Export_Data()
Dim cnn As ADODB.Connection
Dim rst As ADODB.Recordset
Dim dbPath
Dim x As Long, i As Long
Dim nextrow As Long
On Error GoTo errHandler:
dbPath = ActiveSheet.Range("S3").Value
nextrow = Cells(Rows.Count, 1).End(xlUp).row
Set cnn = New ADODB.Connection
If Sheet8.Range("A2").Value = "" Then
MsgBox " Lisa kirjed tellimusse, midagi pole arhiveerida"
Exit Sub
End If
cnn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPath
Set rst = New ADODB.Recordset
rst.Open Source:="Tellimused", ActiveConnection:=cnn, _
CursorType:=adOpenDynamic, LockType:=adLockOptimistic, _
Options:=adCmdTable
For x = 2 To nextrow
rst.AddNew
For i = 1 To 16
rst(Cells(1, i).Value) = Cells(x, i).Value
Next i
rst.Update
Next x
rst.Close
cnn.Close
Set rst = Nothing
Set cnn = Nothing
MsgBox " Tellimus on edukalt arhiiveeritud"
Application.ScreenUpdating = True
Sheet8.Range("R3").Value = Sheet8.Range("T3").Value + 1
Sheet8.Range("A2:P250").ClearContents
On Error GoTo 0
Exit Sub
errHandler:
Set rst = Nothing
Set cnn = Nothing
MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure Export_Data"
End Sub
I think, after these lines code, macro ends and give a error messages. For clarity.
For x = 2 To nextrow
rst.AddNew
For i = 1 To 16
rst(Cells(1, i).Value) = Cells(x, i).Value
Next i
rst.Update
Next x
I would recommend to use some recognizable value in your formula that the macro can read (like 999999) instead of "" and handle it inside macro:
If Cells(x, i).Value <> 999999 Then
rst(Cells(1, i).Value) = Cells(x, i).Value
Else
rst(Cells(1, i).Value) = "" ' or skip
End If
I fix my problem with paste if anybody got similar issue:
Sub Copy_Data()
Worksheets("Sheet1").Range("A2:P250").Copy
Worksheets("Sheet1").Range("U2:AJ250").PasteSpecial xlPasteValues
End Sub

Append data to Excel column using VB6 ADO

I am testing a sample VB6 application which inserts text from TextBox to Excel.
I would like to find the last used row in the column, and append text from txt1 TextBox at the next row whenever user clicks a button.
The range is from C10 to C49.
After the last row is filled, I will prompt user to open new Excel file.
I am unable to do the appending part. Below is the code I tried:
Private Sub cmdUpdate_Click()
Dim objConn As New ADODB.Connection
Dim szConnect As String
szConnect = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\Excel\Format.xls;" & _
"Extended Properties='Excel 8.0;HDR=NO';"
objConn.Open szConnect
Dim xrow As Integer
Dim lastRow As Integer
lastRow = 10
xrow = 49
Do while lastRow <= xrow
objConn.Execute "UPDATE [Sheet1$C" & lastRow & ":C" & lastRow & "] SET F1 =" & txt1.Text & ";"
lastRow = lastRow + 1
Loop
End Sub
The code fills the whole range on each update. I know where my mistake is, but can't figure out proper way. How to make it insert only once until row 49?
Using Excel Object model is not an option as I want to be able to make updates when workbook is open in Excel.
Simple way to achieve this would be to declare your lastRow as more visible (e.g. as private member of your form class), drop looping, and increment lastRow only once per update:
Private lastRow As Integer
'...
objConn.Execute _
"UPDATE [Sheet1$C" & lastRow & ":C" & lastRow _
& "] SET F1 =" & txt1.Text & ";"
lastRow = lastRow + 1
If you assume no complete control over the target Excel range (e.g. data in the range may be modified between your updates, and you do not wish to overwrite those changes) then you could search for the first empty cell before every update. Use IsNull() to test for empty cells.
Private Const RANGE_IS_FULL As Long = -1
' Returns first vacant position in sRange Excel range (zero-based)
' Returns RANGE_IS_FULL if no vacant position was found
' sConnectionString: connection string to Excel workbook
' sRange: Excel range of a form [Sheet1$C10:C49]
Private Function GetNextAppendPosition(sConnectionString As String _
, sRange As String) As Long
Dim lRow As Long
Dim oRS As ADODB.Recordset
Set oRS = New ADODB.Recordset
oRS.CursorLocation = ADODB.adUseClient
oRS.Open "SELECT F1 FROM " & sRange _
, sConnectionString
oRS.MoveFirst
GetNextAppendPosition = RANGE_IS_FULL
lRow = -1
While Not oRS.EOF
lRow = lRow + 1
If IsNull(oRS.Fields(0).Value) Then
GetNextAppendPosition = lRow
GoTo hExit
End If
oRS.MoveNext
Wend
hExit:
oRS.Close
End Function
With this in mind, your update routine could be coded as this:
Public Sub ExportTextToExcelRow(sText As String)
Const CONNECTION_STRING As String = _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\src\Excel ADO\Book1.xls;" & _
"Extended Properties='Excel 8.0;HDR=NO'; "
Const MAX_TARGET_ROW As Long = 49
Const MIN_TARGET_ROW As Long = 10
Const TARGET_COL As String = "C"
Const TARGET_SHEET As String = "Sheet1"
Dim lRow As Long
Dim oConn As New ADODB.Connection
Dim sTargetRange As String
sTargetRange = "[" & TARGET_SHEET & "$" & TARGET_COL & MIN_TARGET_ROW _
& ":" & TARGET_COL & MAX_TARGET_ROW & "]"
lRow = GetNextAppendPosition(CONNECTION_STRING, sTargetRange)
If lRow = RANGE_IS_FULL Then
MsgBox "Oops, range is full."
Exit Sub
End If
lRow = lRow + MIN_TARGET_ROW
sTargetRange = "[" & TARGET_SHEET & "$" & TARGET_COL & lRow _
& ":" & TARGET_COL & lRow & "]"
oConn.Open CONNECTION_STRING
oConn.Execute "UPDATE " & sTargetRange & " SET F1 = """ & sText & """;"
oConn.Close
End Sub
Call it from your event handler this way:
Private Sub cmdUpdate_Click()
ExportTextToExcelRow txt1.Text
End Sub

Resources