Modify multiple records via listbox based on combobox in Access - vba

I have a form that has a multi-selection listbox based on a query of items that have a specific field that is blank (UserID). I would like to select a UserID from a combobox and click a button to have all selected records modified to have that UserID. (I would also like to update the DateAssigned field to whatever the current date is). CaseID is the unique value in the table.
Sample Form Picture
(The combo box has two columns, the second one has the actual ID I'd want to use).
I've looked at multiple different posts on here like this but I haven't been able to get it to work. Here's an example of a code I found and tried, altered slightly.
Private Sub AssignButton_Click()
Dim lCnt As Long
Dim lID As Long
Dim sSQL_Update As String
Dim sText_1 As String
Dim bSuccess As Boolean
sText_1 = Me.ComboBox
With Me.ToAssignList
For lCnt = 1 To .ListCount
If .Selected(lCnt) Then
lID = .Column(4, lCnt - 1)
'Example update for 1 column
sSQL_Update = "UPDATE MainData SET UserID = '" & sText_1 & "' WHERE CaseID = " & lID & ";"
bSuccess = Update_Statement(sSQL_Update)
End If
Next
End With
End Sub
Public Function Update_Statement(sUpdate_Stmt) As Boolean
Dim db As Database
Set db = CurrentDb
db.Execute (sUpdate_Stmt)
End Function
When I try running this nothing happens.
Thank you!

Hy, Some remarks and tweaks to your code :
First enable the direct screen :
This will enable you to use the debug function.
Is the field : UserID in the table Maindata a text field ? If so, fine, otherwise you should alter the string to :
"UPDATE MainData SET UserID = " & Cint(sText_1) & " WHERE CaseID = " & lID & ";"
Then it would be better to create different functions in a module for what you are trying to do. But ok, this is not your main concern right now...
Try :
Private Sub AssignButton_Click()
Dim lCnt As Long
Dim lID As Long
Dim sSQL_Update As String
Dim sText_1 As String
Dim bSuccess As Boolean
sText_1 = Me.ComboBox
With Me.ToAssignList
For lCnt = 1 To .ListCount
If .Selected(lCnt) Then
lID = .Column(4, lCnt - 1)
'Example update for 1 column
sSQL_Update = "UPDATE MainData SET UserID = '" & sText_1 & "' WHERE CaseID = " & lID & ";"
'
'Check your sql statement and add it to stack overflow if it still is not working
'
Debug.Print sSQL_Update
'
bSuccess = Update_Statement(sSQL_Update)
End If
Next
End With
End Sub
There is should be a logical check in the code bellow to see if the update is done, anyhow, the code bellow should work and return a true value if the update doesn't produce an error... it's not good code but ok.
Public Function Update_Statement(sUpdate_Stmt) As Boolean
Dim Currentdb As Database
Set Currentdb = Currentdb
Call Currentdb.Execute(sUpdate_Stmt, dbSeeChanges)
Update_Statement = True
End Function
Good luck !

Related

Data Type Mismatch on SQL statement

I am trying to pull in column data from a table into a timer in VBA. In my table I have IntervalSeconds as a number. I'm trying to query the number of seconds to determine how long to set my counter for.
Dim timeRemaining As Long (Form Variable) - used in multiple functionss
Private Sub Form_Open(Cancel As Integer)
Dim strSQL As String
Me.Visible = False
strSQL = "SELECT AccessControl.IntervalSeconds FROM AccessControl WHERE AccessControl.DatabaseName = '" & CurrentDb.Name & "'"
timeRemaining = CLng(strSQL)
DoCmd.OpenForm ("frmForceLogout")
End Sub
Every time I run the form I get a Type Mismatch error when I hit the timeRemaining = cLng(strSQL) line. Am I missing something?
You can use DLookup for such simple tasks:
Private Sub Form_Open(Cancel As Integer)
Dim Criteria As String
Me.Visible = False
Criteria = "DatabaseName = '" & CurrentDb.Name & "'"
timeRemaining = DLookup("IntervalSeconds", "AccessControl", Criteria)
DoCmd.OpenForm ("frmForceLogout")
End Sub

MS Access capture certain group of text, append, and loop onto next section in a long text field

I have a long text field (called "reporttext") that someone is importing a bunch of text that needs to be separated and appended into another table. For each case, there's a "[]" character that is supposed to separate each case. I want my code to look for the first [] and second [], append the text to another table and then loop. So the next case would be the text between the second [] and third [].
Here's my string
Reporttext: [] ksfjjls [] 42244 [] ####
I would want this to append to a new table called "notes" where it would be like this:
Reporttext
ksfjjls
42244
####
I used a macro to count the number of [] in the text file to know how many times to run the loop, but this, along with the rest of my code just isn't happening. I know my code is wrong, but I know with a few tweaks it'll get there. Any help is appreciated.
lengthofnote = Len([reporttext])
start = InStr([reporttext], "[]")
startplus3 = [start] + 3
'find number of cases
firstcase = 1
numcases = StringCountOccurrences([reporttext], "[]")
Dim LCounter As Integer
For LCounter = [firstcase] To [numcases]
revisedreporttext = Mid([reporttext], [startplus3], [lengthofnote])
secondposition = InStr([revisedreporttext], "[]")
nextreporttext = Mid([reporttext], [startplus3], [secondposition])
Add_reporttext = "INSERT INTO notes(reporttext) values ('" & nextreporttext & "');"
DoCmd.RunSQL Add_reporttext
firstcase = firstcase + 1
startplus3 = secondposition
secondposition = secondposition + 4
Next LCounter
#Zev Spitz is correct in that you could use Split() to accomplish this. You could use something like this
Option Compare Database
Option Explicit
Sub SplitLongTextField()
Dim rs As Recordset
Dim reportTextArr
Dim qString As String
Dim i As Long
qString = "SELECT [reporttext] FROM [Table1]" '<- replace [Table1] with the name of your table with the Long Text field
Set rs = CurrentDb.OpenRecordset(qString)
If Not rs.EOF Then
reportTextArr = Split(rs.Fields("reporttext"), "[]")
End If
For i = LBound(reportTextArr) To UBound(reportTextArr)
If Not reportTextArr(i) = "" Then
DoCmd.RunSQL "INSERT INTO notes(reporttext) VALUES('" & reportTextArr(i) & "');"
End If
Next i
rs.Close
End Sub
If you needed to do this for multiple records from your initial table then you could loop through the entire table and loop the operation like
Option Compare Database
Option Explicit
Sub SplitLongTextField()
Dim rs As Recordset
Dim reportTextArr
Dim qString As String
Dim i As Long
qString = "SELECT [reporttext] FROM [Table1]" '<- replace [Table1] with the name of your table with the Long Text field
Set rs = CurrentDb.OpenRecordset(qString)
Do Until rs.EOF
reportTextArr = Split(rs.Fields("reporttext"), "[]")
For i = LBound(reportTextArr) To UBound(reportTextArr)
If Not reportTextArr(i) = "" Then
DoCmd.RunSQL "INSERT INTO notes(reporttext) VALUES('" & reportTextArr(i) & "');"
End If
Next i
rs.MoveNext
Loop
rs.Close
End Sub
Assuming the string always starts with [] and preference is to return a single string, consider:
Replace(Mid(reporttext, 4), "[] ", vbCrLf)

GoToRecord works fine, but simpliest way to return value for that record

Part of the issue is opening the table for the record set and having to set focus to the subform. I have been unsuccessful in sorting the table through vba. The goal is to find the MEDIAN value of a table, hence the sorting.
Private Sub cboUser_AfterUpdate()
Dim sourceReset As String
Dim dbMedian As DAO.Database
Dim rsMedian As DAO.Recordset
sourceReset = sbf.SourceObject '<--Is Table.TEMPtable btw.
Me.sbf.SourceObject = ""
Forms!frm.Requery
Forms!frm.Refresh
'Create new TEMPtable
DoCmd.SetWarnings False
DoCmd.OpenQuery "qryTEMPtable" '<--Is sorted here as desired
DoCmd.SetWarnings True
Set dbMedian = CurrentDb()
Set rsMedian = dbMedian.OpenRecordset("TEMPtable") '<--Gets unsorted here
sbf.SourceObject = sourceReset
Me.OrderBy = "NetWrkDays ASC" '<--Re-sorting, but on subform, which.. is
fine if I can return the column value later.
Forms!frm.Refresh
Me.[sbf].SetFocus
Records= DCount("[ColA]", "TEMPtable")
'Even number of records
If Records - 2 * Int(Records / 2) = 0 Then
MEDrcd = Records / 2
DoCmd.GoToRecord , , acGoTo, MEDrcd '<-Can see value in debug, how to
assign it to a useful variable???
''''Me.CurrentRecord ("NetWrkDays")
''''Me.RecordSource ("NetWrkDays")
Me.txtMED = rsMedian("NetWrkDays")
End If
'Odd number of records
If Records - 2 * Int(Records / 2) = 1 Then
MEDrcd1 = (Records - 1) / 2
MEDrcd2 = (Records + 1) / 2
DoCmd.GoToRecord acDataForm, "TempTable", acGoTo, MEDrcd1
MED1 = rsMedian("NetWrkDays")
DoCmd.GoToRecord acDataForm, "TempTable", acGoTo, MEDrcd2
MED2 = rsMedian("NetWrkDays")
Me.txtMED = (MED1 + MED2) / 2
End If
I guess I see no point in trying to use DoCmd.GoToRecord if you cant return the value at that point.
What is the best/correct method for returning a value after moving to a record.
As the subform and table are the same, I just ran with setting focus to the subform as I said was having issue sorting the table in vba. Though then me using rsMedian makes no sense, as the table rs never moves...but I cant retrieve a value for moving though the subform using GoToRecord.
I am going in circles here and i hope is not to garbled to understand. Thank you.
Found this method online. Is working great in case anyone else finds themselves in a similar situation.
Private Sub cboUser_AfterUpdate()
Dim sourceReset As String, sqlMED As String, sTable As String, sField As String
Dim j As Integer, varVal As Single
Dim rs As DAO.Recordset
sourceReset = sbf.SourceObject
Me.sbf.SourceObject = ""
Forms!frmSTATS.Requery
Forms!frmSTATS.Refresh
'Create new TEMPtable table
DoCmd.SetWarnings False
DoCmd.OpenQuery "qryTEMPtable"
DoCmd.SetWarnings True
'Get MEDIAN Data/Value
sTable = "TEMPtable"
sField = "NetWrkDays"
sqlMED = "SELECT " & sField & " from " & sTable & " WHERE " & sField & ">0 Order by " & sField & ";"
Set rs = CurrentDb.OpenRecordset(sqlMED)
rs.MoveLast
j = rs.RecordCount
rs.Move -Int(j / 2)
If j Mod 2 = 1 Then 'odd number of elements
getMedian = rs(sField)
Else 'even number of elements
varVal = rs(sField)
rs.MoveNext
varVal = varVal + rs(sField)
getMedian = varVal / 2
End If
Me.txtAnswer = getMedian
rs.Close
sbf.SourceObject = sourceReset
Me.OrderBy = "NetWrkDays ASC"
Forms!frmSTATS.Refresh
End Sub

There is an issue with my code here, can someone look?

I have a listview box that gets populated with five items. Here's the code that I used to populate it
Dim rs As New ADODB.Recordset
Set rs = New ADODB.Recordset
Dim lvwItem As ListItem
Dim x As Integer
lvwExpenditures.ListItems.Clear
With lvwExpenditures
.FullRowSelect = True
.View = lvwReport
.LabelEdit = lvwManual
.ColumnHeaders.Add , "FldName", "EXPENSES", 2200
.ColumnHeaders.Add , "ID", "ID", 0
End With
g_strSQL = "Select FldName, ID, Label, SortOrder from dbo.tblText_References where fldname ='expenditureitems'"
rs.Open g_strSQL, g_cnDatabase, adOpenStatic
Debug.Print g_strSQL
With rs
Do While Not .EOF
Set lvwItem = lvwExpenditures.ListItems.Add(, , .Fields("Label").Value)
lvwItem.SubItems(1) = .Fields("ID").Value 'Populate Date column
.MoveNext
Loop
End With
Set rs = Nothing
What I'm trying to do is let the user select multiple items, concatenate the items (with a comma) and insert them into a table. Here's the code I have for trying to take the selected items and concatenate them (I built a function), but the issue is, it takes one of the items, and concatonates it three times (when three items were selected in listview). I show the label and save the ID, so the when listview is loaded the ID's go in this order 10,11,12,13,14. On my last try, I selected the top three items and the function converted it to (13,13,13). How do I fix it? I know its a small issue
dim x As Integer
Dim mystring As String
For x = 1 To lvwExpenditures.ListItems.Count
If lvwExpenditures.ListItems(x).Selected = True Then
If x = 1 Then
mystring = lvwExpenditures.SelectedItem.SubItems(1)
Else
mystring = mystring & "," & lvwExpenditures.SelectedItem.SubItems(1)
End If
Else
End If
Next x
dim x As Integer
Dim mystring As String
dim sep as string
sep=", "
For x = 1 To lvwExpenditures.ListItems.Count
If lvwExpenditures.ListItems(x).Selected Then
mystring = mystring & lvwExpenditures.ListItems(x).SubItems(1) & sep
End If
Next x
if mystring<>"" then
mystring=left(mystring,len(mystring)-len(sep)
end if

VBA function to a field name

I have the same copy of a function in many forms that does exactly the same job. What changes in them is a field name. So the reason I keep it local is I don't know how I would refer to a particular field by name in a referenced form. This is the function:
Private Function getNewXNo(ByRef theForm As Form, ByVal strCode As String) As String
Dim rs As DAO.Recordset
Dim maxNo As Long
Dim aNo As Long
Set rs = theForm.RecordsetClone
maxNo = 0
If rs.RecordCount <> 0 Then
rs.MoveFirst
Do While Not rs.EOF
aNo = CLng(Right(Nz(rs!applicationNo, strCode & "0000"), 4))
If aNo > maxNo Then
maxNo = aNo
End If
rs.MoveNext
Loop
End If
getNewXNo = strCode & Format(maxNo + 1, "
Set rs = Nothing
End Function
There are a lot of instances when I have to generate new codes, such as BB001, BB002, APP001, APP002, etc. The function reads all existing codes from a field in the referenced form and based on that creates a new one. Is there any way I can send a field name to a global function, such as
aNo = CLng(Right(Nz(rs!varThatContainsAFieldName, strCode & "0000"), 4))
Thanks
You can access a field in a recordset like this:
rs("fieldname")
So you could make the field name a parameter for your function.