Doing data analysis for a lab and I have a table of samples that failed and all the criteria they could've failed on. Trying to add a field with a string listing which criteria each sample failed on.
I just learned VBA 2 weeks ago so I don't really know what I'm doing. I used recordset to turn my table into an array, then looped through each record to see if each criteria has failed and add it to a new failure array if it has. Then I print the failure array in an ugly concatenated string. There are less than 100 records but it's still very slow and sometimes crashes Access. Here's my code:
Option Compare Database
Option Explicit
Dim arrFails() As Variant
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim HType As Integer
Dim S As Integer
Public Sub MakeArrs()
On Error GoTo ErrorHandler
Set db = CurrentDb
'Set rs = db.OpenRecordset("S" & HType & "RptSimple")
Set rs = db.OpenRecordset("S31RptSimple")
rs.MoveLast
rs.MoveFirst
S = rs.RecordCount - 1
Debug.Print S
Dim arrRpt() As Variant
arrRpt = rs.GetRows(S + 1)
Debug.Print arrRpt(0, 0)
'This line creates an array arrFails with sample runs as rows, and 9 columns. Each column is a failure criteria.
ReDim arrFails(0 To S, 0 To 8) As Variant
Dim i As Long
Let i = 0
Dim index As Long
'This For loop starts at the first record in arrRpt and goes across the row with an If loop for each of the failure criteria.
'If the sample failed for that criteria, it populates the new arrFails array with the name of the criteria.
'If the sample passed, that spot on the array stays null.
'At the end of one loop, we have a row that ONLY has values for the criteria that failed.
For index = 0 To S
If arrRpt(2, i) < 0.85 Or IsNull(arrRpt(2, i)) = True Then
arrFails(i, 0) = "Correlation, "
End If
If arrRpt(3, i) > -0.4 Or arrRpt(3, i) < -2 Or IsNull(arrRpt(3, i)) = True Then
arrFails(i, 1) = "Slope, "
End If
If arrRpt(4, i) < 0.5 Or arrRpt(4, i) > 100 Or IsNull(arrRpt(4, i)) = True Then
arrFails(i, 2) = "Slope_Ratio, "
End If
If arrRpt(5, i) < 2 Or IsNull(arrRpt(5, i)) = True Then
arrFails(i, 3) = "Valid_Points, "
End If
If IsNull(arrRpt(6, i)) = False Then
arrFails(i, 4) = "Fail_Code, "
End If
If arrRpt(7, i) < 1.5 Or arrRpt(7, i) > 10 Or IsNull(arrRpt(7, i)) = True Then
arrFails(i, 5) = "DilutionRatio1, "
End If
If arrRpt(8, i) < 1.5 Or arrRpt(8, i) > 10 Or IsNull(arrRpt(8, i)) = True Then
arrFails(i, 6) = "DilutionRatio2, "
End If
arrFails(i, 8) = arrRpt(0, i)
i = i + 1
Next
rs.Close
'This is error handling code, so if something goes wrong it'll gracefully exit the code instead of getting some poor user stuck in debug hell.
ExitSub:
Exit Sub
ErrorHandler:
MsgBox "There's been an error."
Resume ExitSub
Set rs = Nothing
Set db = Nothing
End Sub
Public Function FailList2(HPVType, UIDFieldname)
HType = HPVType
Call MakeArrs
Dim x As Variant
x = 0
Do While x < S + 1
If UIDFieldname = arrFails(x, 8) Then
FailList2 = arrFails(x, 1) & arrFails(x, 0) & arrFails(x, 2) & arrFails(x, 3) & arrFails(x, 4) & arrFails(x, 5) & arrFails(x, 6)
Exit Do
End If
x = x + 1
Loop
End Function
Help a newbie out? There must be a more efficient way to do this. I tried turning echo off until the end of the FailList2 function but it didn't help. Note that I need to keep 'Htype' in the function. I'm just running this on one table right now, but when I fix it I have 8 more tables to run it on, hence the rs code I commented out at the beginning.
I have that function as a field in a query
Uh-oh. There is the problem. Just open the Immediate window, open your query and watch the Debug.Print statements roll in. The function will be executed over and over again.
You need to execute the function once, write the results not into an array (arrFails), but into a table instead. Use Recordset.AddNew to add records.
Then use that table as input for your query.
Related
I have Access data I'm trying to export to a Word table. The table has 3 columns, the first row and first column are all headers.
I'm trying to loop through the recordset and populate columns 2 & 3 with data. I'm able to start at row 2 and populate columns 2 and 3, but I cannot figure out how to move to the next row.
iTbl = 1
irow = 2
iCol = 1
Do Until recSet2.EOF
If irow > wDoc.Tables(iTbl).Rows.Count Then
wDoc.Tables(iTbl).Rows.Add
End If
For Each fld In recSet2.Fields
On Error Resume Next
iCol = iCol + 1
wDoc.Tables(iTbl).Cell(irow, iCol).Range.Text = Nz(fld.Value)
Next fld
recSet2.MoveNext
irow = irow + 1
iCol = 1
Loop
The best way to create a table in Word, especially one with a lot of data, is to first write the data into a character-delimited string format. Assign the string to a Range in Word, then use the ConvertToTable method to turn it into a table. That will save a lot of trouble with manipulating the object model and is the most efficient approach (fastest in execution).
The following code demonstrates this principle. The procedure Test creates a new instance of Word, creates a new document in the Word application then assigns the character-delimited string to the document content. This is then turned into a table. If you need to format that table, use the tbl object to do so. The way this code is written requires a reference to the Word object library (early binding). Note that it's also possible to use late-binding - you'll find loads of examples for that.
The second procedure, concatData is called in Test to create the character delimited string. It uses a Tab character as the field separator and a carriage return as the record separator. Word will accept pretty much anything as the field separator; the record separator must be a carriage return (ANSI 13).
Sub Test()
Dim wd As Word.Application
Dim doc As Word.Document
Dim rng As Word.Range
Dim tbl As Word.Table
Set wd = New Word.Application
wd.Visible = True
Set doc = wd.Documents.Add
Set rng = doc.Content
rng.Text = concatData()
Set tbl = rng.ConvertToTable
End Sub
Public Function concatData() As String
Dim retVal As String
Dim rsHeader As Long, rsCounter As Long
Dim rs As Recordset
Set rs = CurrentDb.OpenRecordset("nameOfRecordset", dbOpenDynaset)
'Get headers
For rsHeader = 0 To rs.Fields.Count - 1
retVal = retVal & rs.Fields(rsHeader).Name & vbTab
Next
'Replace last TAb with a carriage return
retVal = Left(retVal, Len(retVal) - 1) & vbCr
Do While Not rs.EOF
'Get all records
For rsCounter = 0 To rs.Fields.Count - 1
retVal = retVal & rs.Fields(rsCounter).Value & vbTab
Next
retVal = Left(retVal, Len(retVal) - 1) & vbCr
rs.MoveNext
Loop
concatData = retVal
End Function
Thanks for all the help guys. I managed to figure it out and works very well. It wouldn't move down to the next row and was attempting to write data to column(4) which doesn't exist, then throwing an error. Here is the code I used:
iTbl = 1
iRow = 2
iCol = 1
For Each fld In recSet2.Fields
iCol = iCol + 1
If iCol < 4 Then
wDoc.Tables(iTbl).Cell(iRow, iCol).Range.Text = Nz(fld.value)
Else
If iCol > 3 Then
iCol = iCol - 2
iRow = iRow + 1
wDoc.Tables(iTbl).Cell(iRow, iCol).Range.Text = Nz(fld.value)
End If
End If
Next fld
I am trying to delete duplicate records in MS ACCESS.
I have created a query that is sorted on field name.
I have VBA code that runs through the query, and then when finds a match it deletes the record - however it is not picking up the match.
My code looks as follows:
Dim db As DAO.Database
Dim recIn As DAO.Recordset
Dim strFieldName1 As Variant
Dim strFieldDescr2 As Variant
Dim strDomainCat3 As Variant
Dim strBusinessTerm4 As Variant
Dim strtableName5 As Variant
Dim lngRecordsDeleted As Variant
lngRecordsDeleted = 0
Set db = CurrentDb()
Set recIn = db.OpenRecordset("qryMyRecords")
If recIn.EOF Then
MsgBox ("No Input Records")
recIn.Close
Set recIn = Nothing
Set db = Nothing
Exit Sub
End If
Do
If recIn!FieldName = strFieldName1 And _
recIn!FieldDescr = strFieldDescr2 And _
recIn!DomainCatID = strDomainCat3 And _
recIn!BusinessTermID = strBusinessTerm4 And _
recIn!TableID = strtableName5 Then
recIn.Delete
lngRecordsDeleted = lngRecordsDeleted + 1
Else
strFieldName1 = recIn!FieldName
strFieldDescr2 = recIn!FieldDescr
strDomainCat3 = recIn!DomainCatID
strBusinessTerm4 = recIn!BusinessTermID
strtableName5 = recIn!TableID
End If
recIn.MoveNext
Loop Until recIn.EOF
recIn.Close
Set recIn = Nothing
Set db = Nothing
MsgBox ("You Deleted " & lngRecordsDeleted & " Records")
End Sub
My StrFieldname1, through to to StrTablename5 does populate (after the else statement)
However when I do the compare a second time
If recIn!FieldName = strFieldName1 And _
recIn!FieldDescr = strFieldDescr2 And _
recIn!DomainCatID = strDomainCat3 And _
recIn!BusinessTermID = strBusinessTerm4 And _
recIn!TableID = strtableName5 Then
recIn.Delete
lngRecordsDeleted = lngRecordsDeleted + 1
Even though the values are the same, it moves to the else statement, and never does the record delete.
Now I suspect that this could be because I declared my variables as VARIANT type, but if I use any other type, the code falls over every time it reaches a NULL value in the query, and there are cases where any of the fields from the query can and will be null.
Any suggestions would be greatly appreciated
To expand on what Justin said, use the Nz function in your main If statement, like so:
If Nz(recIn!FieldName, "") = strFieldName1 And _
...
Else
strFieldName1 = Nz(recIn!FieldName, "")
...
The task: Create a report for Part Numbers that shows several types (On Hand, On Order, etc) in date buckets with each type totaled for the specific range.
For example:
Item 1 => (could be over 2000)
2/5/2017 2/19/2017 2/28/2017 (30 weeks)
On Hand 20 42 33
On Order 0 5 4
Each item is shown on it's own page with related metadata about the item. Each date bucket is based on a user-entered start date with a calculation running against the data set to determine what goes in which bucket and what the totals are.
I have this report fully working for one item. User types one item, selects a date, and the report is created using the following:
Inventory Meta general information and description of the item
Inventory Detail gets all the detailed information
Inventory Totals gets totals for each Types
GetInventory() VBA sets up the buckets and populates the totals
Using a query to get the date buckets would perhaps be easier to get the data into the report. Creating a query with 210 calculated columns (7 types, 30 weeks) wasn't a reasonable approach.
Naturally, selecting one item at a time is not what's wanted.
I have a select box that gets whatever Part Numbers are selected and creates a query on the fly for the Inventory Meta (main report). I have similar code working that runs with the Inventory Totals (sub report) to create a query on the fly for that.
But, as with the Inventory Totals query, each date is a unique value and is it's own row. What I need to be able to do is run the code to build the buckets for each item selected.
I'm stuck.
I have created an array of item numbers (whatever was selected). I can see what's in the array.
What I can't seem to figure out is how to feed each to the code that runs the date comparisons and calculations so that I get a full set of data for each Part Number.
With one number it was easy.... "this one"
vItem = [Forms]![fOptions]![ItemNumber]
Set db = CurrentDb
strSelect = "Select * FROM qInventoryTotals WHERE qInventoryTotals.ItemNumber = [this_one]"
Set qdf = db.CreateQueryDef(vbNullString, strSelect)
qdf.Parameters("this_one").Value = vItem
Set inv = qdf.OpenRecordset
The closest I've come is getting the report to show the same set of data for all part numbers. I suspect there is some small but critical thing, like where a particular loop starts or a variable I've missed or something.
The result of the following is a message box that repeats the same total for each of the part numbers.
Private Sub CreateOne_Click()
On Error GoTo Err_cmdOpenQuery_Click
'----------- Selection box check for dates -------------
If IsNull(Forms!fFish1!Week1) Then
MsgBox "A Sunday date must be selected", , "Please select a date"
ElseIf Weekday(Forms!fFish1!Week1) = 1 Then
'MsgBox "That is Sunday"
Forms!fFish1!Week1 = Forms!fFish1!Week1
Else
MsgBox "Starting Week needs to be a Sunday date" _
, , "Sorry, that's not Sunday"
' clears the 'not Sunday' selection
Forms!fFish1!Week1 = ""
Exit Sub
End If
'-------------------------------------------------
' Declarations =====================================
Dim db As DAO.Database
Dim iMeta As DAO.QueryDef
Dim i As Integer
Dim strSQL As String
Dim strWhere As String
Dim strIN As String
Dim flgSelectAll As Boolean
Dim varItem As Variant
Dim strSlect As String
Dim vItem As Variant
' Setup -------------------------------------
Set db = CurrentDb()
strSQL = "SELECT * FROM qInventoryTotals2"
'----------------------------------------------------------------------
' Get whatever is selected and loop through the selections
' This defines which numbers are in the list
'----------------------------------------------------------------------
For i = 0 To Forms!fFish1.box4.ListCount - 1
If Forms!fFish1.box4.Selected(i) Then
If Forms!fFish1.box4.Column(0, i) = "All" Then
flgSelectAll = True
End If
strIN = strIN & "'" & Forms!fFish1.box4.Column(0, i) & "',"
End If
Next i
'Create the WHERE string, and strip off the last comma of the IN string
strWhere = " WHERE [ItemNumber] in " & _
"(" & Left(strIN, Len(strIN) - 1) & ")"
'If "All" was selected in the listbox, don't add the WHERE condition
If Not flgSelectAll Then
strSQL = strSQL & strWhere
End If
'-------------------------------------------------------
' Create a query that has all the selected item numbers
db.QueryDefs.Delete "qInventoryTotals3"
Set iMeta = db.CreateQueryDef("qInventoryTotals3", strSQL)
Set inv = iMeta.OpenRecordset
'==========================================================================
' Create an array to pull out each of the Item numbers one at a time
Dim Count As Integer, r As Integer
Count = 0
For i = 0 To Forms!fFish1.box4.ListCount - 1
If Forms!fFish1.box4.Selected(i) Then
vItem = Forms!fFish1.box4.Column(0, i)
'vItemFilter = Forms!fFish1.box4.Column(0, i)
'MsgBox (vItem), , "one by one"
Count = Count + 1
End If
Next i
''MsgBox (Count), , "count how many items are in the set"
' Get the count for how many items are in the currently selected list
' Displays one item at a time -
' Set up the array ------------------------------
'------------------------------------------------
ReDim vItem(Count)
r = 0
For i = 0 To Forms!fFish1.box4.ListCount - 1
If Forms!fFish1.box4.Selected(i) Then
vItem(r) = Forms!fFish1.box4.Column(0, i)
r = r + 1
End If
Next i
'Check the values stored in array
''For i = 0 To Count - 1
''MsgBox vItem(i), , "show all values from the array"
''Next
' have all values from the array. Each in it's own message box
'===============================================================================
' Set up the item numbers ---------------------------
Dim part As Variant
part = vItem
With vItem
For i = LBound(vItem) To UBound(vItem) - 1
MsgBox ("There are" & " " & (vItem(i)) & " " & "fishies"), , "Whatcha' got now?"
' cycles through each number
' Past Due ============================================
Dim tPOPast As Double
Dim tBCPast As Double
Dim tBPast As Double
Dim tEPast As Double
If inv!ItemNumber = part(i) And inv.Fields("RequiredDate") < Forms!fFish1!Week1 Then
'displays the first part number with it's value, then the remaining numbers with no value
' If inv.Fields("RequiredDate") < Forms!fFish1!Week1 Then
'displays each of the part numbers with the same value
tBPast = inv.Fields("TotalOnHand")
tPOPast = tPOPast + inv.Fields("SumOfSupply")
tBCPast = tBCPast + inv.Fields("SumOfDemand")
' Calculate ending inventory for the week ===================
tEPast = tBPast + tPOPast + tBCPast
' Show something for testing ==============================
MsgBox (tBPast & " " & part(i)), , "show Me the money" ' displays same total for each part number
End If
'end this condition, next condition follows
'----------------- do it again -------------------------------
Next
' Finished with the weekly buckets =====================================
End With
'=========================================================================
'-------------------- error management for the selection box ------------------
Exit_cmdOpenQuery_Click:
Exit Sub
Err_cmdOpenQuery_Click:
If Err.Number = 5 Then
MsgBox "Pick one, or more, item numbers from the list" _
, , "Gotta pick something!"
Resume Exit_cmdOpenQuery_Click
Else
'Write out the error and exit the sub
MsgBox Err.Description
Resume Exit_cmdOpenQuery_Click
End If
'---------------------------------------------------------------------------
End Sub
The solution I found was to set variables for the values from the array and use them to dynamically update a table. From that, I created a query to sum the values and used that as the basis for the report. The key was GetRows()
Get the unique items and read the the rows of data into the first array
Dim rNum As Integer
rNum = myItems.RecordCount
Dim varItem As Variant
Dim intRi As Integer 'rows of unique items
Dim intCi As Integer 'columns of unique items
Dim intNCi As Integer
Dim intRCi As Integer
varItem = myItems.GetRows(rNum)
intNRi = UBound(varItem, 2) + 1
intNCi = UBound(varItem, 1) + 1
For intRi = 0 To intNRi - 1
For intCi = 0 To intNCi - 1
vItem = varItem(intCi, intRi)
Use vItem to dynamically create a new recordset to set up the weekly buckets
strSelect = "Select * FROM qInventoryTotals2 WHERE qInventoryTotals2.ItemNumber = [this_one]"
Set qdf = db.CreateQueryDef(vbNullString, strSelect)
qdf.Parameters("this_one").Value = vItem
Set inv = qdf.OpenRecordset
Count the records, create a second array
Dim invNum As Integer
invNum = inv.RecordCount
Dim varRec As Variant
Dim intR As Integer
Dim intC As Integer
Dim intNC As Integer
Dim intRC As Integer
Dim cItem As String
Dim cRequired As Date
Dim cPO As Double
Dim cBC As Double
Dim cOnHand As Double
varRec = inv.GetRows(invNum)
intNR = UBound(varRec, 2) + 1
intNC = UBound(varRec, 1) + 1
For intR = 0 To intNR - 1
For intC = 0 To intNC - 1
cItem = varRec(0, intR)
cRequired = varRec(1, intR)
cOnHand = varRec(2, intR)
cPO = varRec(3, intR)
cBC = varRec(4, intR)
cSO = varRec(5, intR)
cPD = varRec(6, intR)
cIN = varRec(7, intR)
cJT = varRec(8, intR)
cWO = varRec(9, intR)
'------------- finish getting inventory columns --------------------
Next intC
And then set up the buckets for each week
If cRequired < Week1 Then
recOut.AddNew
recOut.Fields("ItemNumber") = cItem
recOut.Fields("tB") = cOnHand
recOut.Fields("tPO") = cPO
recOut.Fields("tBC") = cBC
recOut.Fields("tSO") = cSO
recOut.Fields("tPD") = cPD
recOut.Fields("tIN") = cIN
recOut.Fields("tJT") = cJT
recOut.Fields("tWO") = cWO
recOut.Fields("tE") = cOnHand + cPO + cBC + cSO + cPD + cIN + cJT + cWO
recOut.Fields("RequiredDate") = cRequired
recOut.Fields("GroupDate") = Week1
recOut.Update
' tE0 = cOnHand + cPO + cBC + cSO + cPD + cIN + cJT + cWO
Dim tryme As Double
tryme = DLookup("teMe", "qBuckets", "GroupDate = Week1")
tE0 = tryme
End If
Ok so i have a complex reason field from one of our logging servers, and i need to break it down to make some sense, problem is the format changes depending on the status.
I managed to find some strings that i can compare the the reason to to get some sense out of it, but I want to distill it down to one reason code.
I scratched my head a bit and got it down to 7 reasons with different criterion, put the criteria in a table and came up with some vb code to do the comparison.
Problem is its dead slow, and half the reporting relies on the Reason code. The basic VBA function is below, This basically loads the criteria into an array and then compares the value against the array to return the ID.
Function Reason_code(LongReason As String) As Integer
Dim NoReason As Integer
Dim I As Integer
Dim J As Integer
Dim x As Boolean
NoReason = recordCount("RejReason") - 1
Dim conExpr() As String
ReDim conExpr(NoReason)
For I = 0 To (NoReason - 1)
conExpr(I) = GetVal("Criterior", "RejReason", "id", CStr(I + 1))
Next I
For J = 0 To (NoReason - 1)
x = LongReason Like conExpr(J)
If x = True Then
GoTo OutOfLoop
End If
Next J
OutOfLoop:
Reason_code = J + 1
End Function
I have used similar in VB before and it tends to be quite fast, so i am reconing that my GetVal function is the problem, but my VBA is rusty and my SQL is pretty non existent, so any help would be appreciated. I tried LSQL and SQL2 as one line but VBA doesnt like it.
Function GetVal(FieldNm As String, TableNm As String, IndexField As String, IndexNo As String) As String
Dim db As Database
Dim Lrs As DAO.Recordset
Dim LSQL As String
Dim LGST As String
Dim SQL2 As String
'Open connection to current Access database
Set db = CurrentDb()
'Create SQL statement to retrieve value from GST table
LSQL = CStr("SELECT " + FieldNm + " FROM " + TableNm)
SQL2 = CStr(LSQL + " WHERE " + IndexField + " = " + IndexNo)
Set Lrs = db.OpenRecordset(SQL2, dbOpenDynaset, dbReadOnly)
'Retrieve value if data is found
If Lrs.EOF = False Then
LGST = Lrs(0)
Else
LGST = "Item Not found"
End If
Lrs.Close
Set Lrs = Nothing
GetVal = LGST
End Function
Thanks in advance,
I Scratched my head for a bit and worked out i could speed it up by doing the read and compare at the same time, its not lightning, but its better
Function ReasonCode(LongReason As String) As String
Dim cdb As Database
Dim rs As DAO.Recordset
Dim RejRea()
Dim NoReason As Integer
Dim result As Boolean
Dim i As Integer
Set cdb = CurrentDb()
Set rs = cdb.OpenRecordset("RejReason", dbOpenDynaset, dbReadOnly)
rs.MoveLast
rs.MoveFirst
NoReason = rs.recordCount - 1
RejRea() = rs.GetRows(rs.recordCount)
For i = 0 To NoReason
result = LongReason Like CStr(RejRea(2, i))
If result = True Then
ReasonCode = CStr(RejRea(1, i))
GoTo outloop
End If
Next i
If ReasonCode = "" Then ReasonCode = "Not Found"
outloop:
Set rs = Nothing
Set cdb = Nothing
End Function
Still not sure its the best way to do it, but in the abscence of any other suggestions it will do for now.
I have retrieve all data from the internet into a 2 dimension array, I know how to use vba recordset and by filter and update using loop. Below is part of the code in vba.
the difficult problem is here:
Using cmd As New MySqlCommand("INSERT INTO `calls` (`CID`, `ctype`) VALUES (#CID, #ctype)", cnn)
This make me could not use any loop through the array and update accordingly.
cmd.Parameters.Add ('#CID').value = arrValue(i,j)
I hope this could be done in kind of below:
for x = 0 to ubound(arrValue,0)
for y = 0 to ubound(arrValue,1)
.fields(arrHeader(y) = arrValue(x,y)
next y
next x
say i, the n-th to be updated, j = the value of the header
extract of vba:
With rs
'Worksheets(strWsName).Activate
'iLastRow = Worksheets(strWsName).Cells(65535, 1).End(xlUp).row 'column B, column 2
For i = 0 To UBound(arrValue, 1)
Debug.Print "Updating " & i + 1 & " of " & UBound(arrValue, 1) + 1 & " news ..." ' of " & strCodeAB & " ..."
'Start looping the news row
strNewsID = arrValue(i, 1) 'Worksheets(strWsName).Range(ColRefNewsID & i).Value
If strNewsID = "" Then
Debug.Print i - 1 & " news is updated to database"
i = UBound(arrValue, 1)
Else
strFilter = "fID='" & strNewsID & "'"
rs.Filter = strFilter
If rs.EOF Then
.AddNew 'create a new record
'add values to each field in the record
For j = 0 To UBound(arrTitle_ALL)
'20140814
strFieldValue = .Fields(arrAccessField(j))
strNewValue = arrValue(i, j)
If IsNull(strFieldValue) And strNewValue = "" Then
Else
.Fields(arrAccessField(j)) = arrValue(i, j) 'Worksheets(strWsName).Cells(i, j + 1).Value
End If
Next j
On Error Resume Next '***************
.Update 'stores the new record
On Error GoTo 0
iCounterNewsAdded = iCounterNewsAdded + 1
glcounterNewsAdded = iCounterNewsAdded
Else
It seems that the below post similar to my request but I don't know how to do so.
[reference]passing an Array as a Parameter to be used in a SQL Query using the "IN" Command
The post you mention (Using the IN() command) works in your WHERE clause but it is not valid for values. MySQL has no way to pass an array so you need to loop through your array and run multiple INSERT statements:
for y = 0 to ubound(arrValue,1)
cmd.Parameters.AddWithValue(#CID,arrValue(0,y))
cmd.Parameters.AddWithValue(#ctype,arrValue(1,y))
cmd.ExecuteNonQuery
next y