This SELECT CASE scenario is working for me but I think the code can be more friendly ... any advice would be very helpful.
Select Case True 'select case where worker name and action is true then in each case RSworkhours.addnew
Case Me.Worker1.Value <> "" And Me.fw1a1 = 1
With RsWorkHours
.AddNew
!WorkerID = Me.Worker1
!Date = Me.TxtDate
!StandardTime = Me.w1a1s
!Overtime = Me.w1a1o
!Doubletime = Me.w1a1d
!ScaffoldID = Me.cboScaffnum
.Update
End With
Me.fw1a1 = 0
GoTo WorkerHours
Case Me.Worker1.Value <> "" And Me.fw1a2 = 1
With RsWorkHours
.AddNew
!WorkerID = Me.Worker1
!Date = Me.TxtDate
!StandardTime = Me.w1a2s
!Overtime = Me.w1a2o
!Doubletime = Me.w1a2d
!ScaffoldID = Me.cboScaffnum
.Update
End With
Me.fw1a2 = 0
GoTo WorkerHours
The Code iterates through this Select Case 80 times, if there are 16 workers and each have 5 actions.
I was thinking maybe having a loop that modifies the number within the arguments like:
for each x to 16
for each y to 5
If Me.worker & x & .Value <> "" And Me.fw & x & a & y Then
With Recordset
.AddNew
'insert stuff
.Update
End With
End If
Next y
Next x
Does anyone have any insight?
Thank you in advance.
-Matt
You can access all controls by their name from the Controls collection.
Just pass the name of a control and you will get to that control - the name is a string and can of course be dynamic.
Dim x As Long, y As Long
Dim WorkerX As Control, wXaYs As Control, wXaYo As Control, wXaYd As Control
For x = 1 To 16
For y = 1 To 5
Set WorkerX = Me.Controls("Worker" & x)
Set wXaYs = Me.Controls("w" & x & "a" & y & "s")
Set wXaYo = Me.Controls("w" & x & "a" & y & "o")
Set wXaYd = Me.Controls("w" & x & "a" & y & "d")
If WorkerX.Value > "" And wXaYs.Value > "" Then
With Recordset
.AddNew
!WorkerID = WorkerX.Value
!Date = Me.TxtDate
!StandardTime = wXaYs.Value
!Overtime = wXaYo.Value
!Doubletime = wXaYd.Value
!ScaffoldID = Me.cboScaffnum
.Update
End With
End If
Next y
Next x
Related
I have a function called "CurveInterpolateRecordset", which is as follows:
Function CurveInterpolateRecordset(rsCurve As Recordset, InterpDate As Date) As Double
Dim I As Long
Dim x1 As Date, x2 As Date, y1 As Double, y2 As Double, x As Date
CurveInterpolateRecordset = Rnd()
If rsCurve.RecordCount <> 0 Then
I = 1
rsCurve.MoveFirst
x1 = CDate(rsCurve.Fields("MaturityDate"))
y1 = CDbl(rsCurve.Fields("ZeroRate"))
If InterpDate = CDate(rsCurve.Fields("MaturityDate")) Then CurveInterpolateRecordset = CDbl(rsCurve.Fields("ZeroRate")): Exit Function
'Do While Not rsCurve.EOF
rsCurve.MoveNext
Do While (CDate(rsCurve.Fields("MaturityDate")) <= InterpDate)
If rsCurve.EOF Then CurveInterpolateRecordset = CDbl(rsCurve.Fields("ZeroRate")): Exit Function
If InterpDate = CDate(rsCurve.Fields("MaturityDate")) Then CurveInterpolateRecordset = CDbl(rsCurve.Fields("ZeroRate")): Exit Function
If InterpDate > CDate(rsCurve.Fields("MaturityDate")) Then
x1 = CDate(rsCurve.Fields("MaturityDate"))
y1 = CDbl(rsCurve.Fields("ZeroRate"))
End If
rsCurve.MoveNext
If rsCurve.EOF Then CurveInterpolateRecordset = y1: Exit Function
Loop
x2 = CDate(rsCurve.Fields("MaturityDate"))
y2 = CDbl(rsCurve.Fields("ZeroRate"))
CurveInterpolateRecordset = y1 + (y2 - y1) * CDate((InterpDate - x1) / (x2 - x1))
End If
Debug.Print I, InterpDate, x1, x2, y1, y2
End Function
This loop will interpolate a missing value for a specific date by interpolating using the values for the nearest dates.
I have a table of dates, some of which need interpolating, so I am using another function to iterate through the recordset and pass the function through each record's corresponding date in order to interpolate the value.
Sub SampleReadCurve()
Dim rs As Recordset
Dim iRow As Long, iField As Long
Dim strSQL As String
Dim CurveID As Long
Dim MarkRunID As Long
Dim ZeroCurveID As String
CurveID = 124
MarkRunID = 10167
ZeroCurveID = "'" & CurveID & "-" & MarkRunID & "'"
'strSQL = "SELECT * FROM dbo_VolatilityInput WHERE ZeroCurveID='124-10167'"
strSQL = "SELECT * FROM dbo_VolatilityInput WHERE ZeroCurveID=" & ZeroCurveID & " ORDER BY MaturityDate"
Set rs = CurrentDb.OpenRecordset(strSQL, Type:=dbOpenDynaset, Options:=dbSeeChanges)
If rs.RecordCount <> 0 Then
Do While Not rs.EOF
rs.MoveFirst
Debug.Print vbCrLf
Debug.Print "First", rs!ZeroCurveID, rs!MaturityDate, rs!ZeroRate, rs!DiscountFactor
rs.MoveLast
Debug.Print "Last", rs!ZeroCurveID, rs!MaturityDate, rs!ZeroRate, rs!DiscountFactor
Debug.Print "There are " & rs.RecordCount & " records and " _
& rs.Fields.Count & " fields."
Dim BucketTermAmt As Long
Dim BucketTermUnit As String
Dim BucketDate As Date
Dim MarkAsOfDate As Date
Dim InterpRate As Double
MarkAsOfDate = rs!MarkAsOfDate
BucketTermAmt = 3
BucketTermUnit = "m"
BucketDate = DateAdd(BucketTermUnit, BucketTermAmt, MarkAsOfDate)
InterpRate = CurveInterpolateRecordset(rs, BucketDate)
Debug.Print BucketDate, InterpRate
rs.MoveNext
Loop
End If
End Sub
For one individual record and date, the first function works fine. However, when I execute the second function, the loop keeps repeating infinitely and the program crashes. I don't understand why this happens because there is clearly an end condition in the second loop. The recordset is only 76 records so not extremely large.
Remove the block that starts with rs.MoveFirst and ends with rs.MoveLast from inside your while loop. They should be inside the if but before the while.
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
In our code, we have a few Excel objects and a few subs and functions.
We edited a few things and now, for some reason, our objects aren't working inside the sub, the give a "Object Required" error.
We don't know what to do anymore, so any help would be greatly appreciated!
Note: We added the entire code in case there would be questions about declarations and that...
Sub:
Sub birthday (formatDate, i, intRow)
'Take date from database, separate it to days & months
Dim month, day, name
eventDate = Split(formatDate,"/")
month = eventDate(0)
day = eventDate(1)
'Get name of event out of database (one column to the right, from date of event)
name = "netch"
'Get value of row which is used to write events in the specific month
Dim k, row, c
k = 1
wscript.echo objXLCal.Cells(k, 2).Value
Do Until objXLCal.Cells(k, 2).Value = monthRet(month)
k = k + 1
Loop
'k will be used to find the day column, while row is where the events of that months are written
row = k + 3
c = 1
'Get value of column
Do Until objXLCal.Cells(k,c).Value = eval(day)
c = c + 1
Loop
'Insert name of event into place
If Asc(name) = 63 Then
objXLCal.Cells(row,c).Value = StrReverse(name)
Else
objXLCal.Cells(row,c).Value = name
End If
End Sub
Rest of code:
main("C:\Users\liatte\Desktop\hotFolder\Input")
Function main(argFilePath)
Dim templatePath
'-----------------------------------------------------------------------------
'Path to calendar template
templatePath = "C:\Users\liatte\Desktop\Aviv Omer Neta\Birthdays\Calendar1.xlsx"
'-----------------------------------------------------------------------------
'creates the msxml object
'Set xmlDoc = CreateObject("Msxml2.DOMDocument.6.0")
'Dim retVal
'load the xml data of the script
'retVal=xmlDoc.load(argFilePath)
Dim fso, folder, sFolder, inputFolder, xmlDataPath, curNode
'get input folder
'Set curNode=xmlDoc.selectSingleNode("//ScriptXmlData/inputFilePath")
'inputFolder=CSTR(curNode.text)
'location of input folder
'sFolder=inputFolder
sFolder=argFilePath
'creating file getting object
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder = fso.GetFolder(sFolder)
'loop that runs on files in input - RUNS JUST ONCE
'For each folderIdx In folder.files
'Creating object for user excel
Set objXLBirth = CreateObject("Excel.Application")
Set objWorkbookBirth = objXLBirth.Workbooks.Open("C:\Users\liatte\Desktop\hotFolder\Input\Birthdays.xlsx")
'Creating object for calendar template excel
Set objXLCal = CreateObject("Excel.Application")
objXLCal.DisplayAlerts = false
Dim picStr, srcMonth, k, i, intRow, formatDate, txtStr
'Beginning reading from line 2, skipping header
intRow = 2
'loop for each person in user excel
Do Until objXLBirth.Cells(intRow,1).Value = ""
i=2
'Opening the template as new in each round of loop
Set objWorkbookCal = objXLCal.Workbooks.Open(templatePath)
'Cover pic
If Not objXLBirth.Cells(intRow, i).Value = "" Then
objXLCal.Cells(2, 49).Value = objXLBirth.Cells(intRow, i).Value
End If
'Month pic inserter
For i=3 To 14
If Not objXLBirth.Cells(intRow,i).Value = "" Then
picStr = objXLBirth.Cells(1,i).Value
srcMonth = monthRet(Mid(picStr,4))
k=1
Do Until objXLCal.Cells(k, 2).Value = srcMonth
k=k+1
Loop
objXLCal.Cells(k, 47).Value = objXLBirth.Cells(intRow,i).Value
End If
Next
i=15
'Cover text inserter
If Not objXLBirth.Cells(intRow, i).Value = "" Then
objXLCal.Cells(2, 50).Value = objXLBirth.Cells(intRow, i).Value
End If
'Month text inserter
For i = 16 To 27
If Not objXLBirth.Cells(intRow,i).Value = "" Then
txtStr = objXLBirth.Cells(1,i).Value
srcMonth = monthRet(Mid(txtStr,5))
k=1
Do Until objXLCal.Cells(k, 2).Value = srcMonth
k=k+1
Loop
If Asc(objXLBirth.Cells(intRow, i).Value)=63 Then
objXLCal.Cells(k, 48).Value = StrReverse(objXLBirth.Cells(intRow, i).Value)
Else
objXLCal.Cells(k, 48).Value = objXLBirth.Cells(intRow, i).Value
End If
End If
Next
i=28
'Birthday inserter
Do Until objXLBirth.Cells(intRow,i).Value = ""
formatdate=FormatDateTime(objXLBirth.Cells(intRow,i),2)
Call birthday (formatdate,i,intRow)
i=i+2
Loop
'saving changed calendar
objXLCal.ActiveWorkBook.SaveAs "C:\Users\liatte\Desktop\Aviv Omer Neta\Birthdays\Calendar_" & objXLBirth.Cells(intRow, 1).Value & ".txt", 42
intRow = intRow+1
Loop
'moving file to Success
'fso.MoveFile inputFolder, "C:\Users\liatte\Desktop\Success\"
'Next
objXLBirth.Quit
objXLCal.Quit
End Function
Another function:
Function monthRet(month)
Select Case month
Case "1"
monthRet="January"
Case "2"
monthRet="February"
Case "3"
monthRet="March"
Case "4"
monthRet="April"
Case "5"
monthRet="May"
Case "6"
monthRet="June"
Case "7"
monthRet="July"
Case "8"
monthRet="August"
Case "9"
monthRet="September"
Case "10"
monthRet="October"
Case "11"
monthRet="November"
Case "12"
monthRet="December"
End Select
End Function
Thank you very much!
Given a code layout like:
Sub birthday (formatDate, i, intRow)
...
wscript.echo objXLCal.Cells(k, 2).Value
...
End Sub
Function main(argFilePath)
...
Set objXLCal = CreateObject("Excel.Application")
...
End Function
main "C:\Users\liatte\Desktop\hotFolder\Input"
an "Object required" error for the WScript.Echo line is to be expected (the local variable objXLCal initialized in main isn't the same as the (therefore) uninitialized local variable objXLCal in birthday).
The correct solution would be to start with "Option Explicit" and follow the principles of decent procedural programming in VBScript, but the disgusting hack of Diming variables like objXLCal at the top/global level won't lower the quality of the published code.
I'm a VBA novice trying to combine these two sub procedures into a single procedure - can anyone provide how to do this?
Basically, I'm trying to add an image to an Access report (in the 2nd code block - it's checking/creating the image path) - where there is already a check for other information from the database product record.
Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
Dim x$, y$, i%
x = ""
For i = 1 To 10
y = Me("txtOp" & i) & ""
If y > "" Then
If x > "" Then x = x & " "
x = x & "Option " & i & ": " & y
End If
Next
If x > "" Then x = CR & x
Me.txtProduct = Me.txtItem & "" & x
If Me.Adjustment Then
Me.txtShowSKU = ""
Else
Me.txtShowSKU = Me.txtSKU
End If
Dim x, y, OK%
OK = False
x = Me.txtImage & ""
If x > "" Then
y = getparm("ImagePath")
If y > "" Then
If Right$(y, 1) <> "\" Then y = y & "\"
If Left$(x, 1) = "\" And Len(x) > 1 Then x = Mid$(x, 2)
If FileExists(y & x) Then OK = True: x = y & x
End If
If OK Then
Me.imgProd.visible = True
Me.imgProd.Picture = x
Else
Me.imgProd.visible = False
End If
End If
End Sub
I think this should work:
Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
Dim x as String
Dim y as String
Dim i as Integer
For i = 1 To 10
y = Me("txtOp" & i) & ""
If y > "" Then
If x > "" Then x = x & " "
x = x & "Option " & i & ": " & y
End If
Next
If x > "" Then x = CR & x
Me.txtProduct = Me.txtItem & "" & x
If Me.Adjustment Then
Me.txtShowSKU = ""
Else
Me.txtShowSKU = Me.txtSKU
End If
Dim OK as Boolean
y = ""
x = Me.txtImage & ""
If x > "" Then
y = getparm("ImagePath")
If y > "" Then
If Right$(y, 1) <> "\" Then y = y & "\"
If Left$(x, 1) = "\" And Len(x) > 1 Then x = Mid$(x, 2)
If FileExists(y & x) Then OK = True: x = y & x
End If
If OK Then
Me.imgProd.visible = True
Me.imgProd.Picture = x
Else
Me.imgProd.visible = False
End If
End If
End Sub
i need to get a list of all possible combinations, not permutations.
to make sure i have the right name, 123 and 321 to me are the same thing and should only be listed once.
the code below does what i need but i can't convert it into MS Access vba.
i'm sorry, i know this is basic and it has been asked a million times but i can't find anything for MS Access that works for me.
Sub test_print_nCr()
print_nCr 7, 3, Range("A1")
End Sub
2.
Public Function print_nCr(n As Integer, r As Integer, p As Range)
c = 1
internal_print_nCr n, r, p, 1, 1
End Function
3.
Public Function internal_print_nCr(n As Integer, r As Integer, ByVal p As Range, Optional i As Integer, Optional l As Integer) As Integer
' n is the number of items we are choosing from
' r is the number of items to choose
' p is the upper corner of the output range
' i is the minimum item we are allowed to pick
' l is how many levels we are in to the choosing
' c is the complete set we are working on
If n < 1 Or r > n Or r < 0 Then Err.Raise 1
If i < 1 Then i = 1
If l < 1 Then l = 1
If c < 1 Then c = 1
If r = 0 Then
p = 1
Exit Function
End If
Dim x As Integer
Dim y As Integer
For x = i To n - r + 1
If r = 1 Then
If c > 1 Then
For y = 0 To l - 2
If p.Offset(c - 1, y) = "" Then p.Offset(c - 1, y) = p.Offset(c - 2, y)
Next
End If
p.Offset(c - 1, l - 1) = x
c = c + 1
Else
p.Offset(c - 1, l - 1) = x
internal_print_nCr n, r - 1, p, x + 1, l + 1
End If
Next
End Function
thank you again
I am not sure if this is the best method to do this, but I would use a kind of binary representation. For instance, consider the word "boy" with the number of letters n=3. This word has three letters, so you can use something like this:
001 = y,
010 = o,
011 = oy,
100 = b,
101 = by,
110 = bo,
111 = boy.
The left side can be done with a loop from i=1 to power(2,n)-1 and transforming i to a number in the binary basis. So, the only thing you have to do is to use the non null positions to build your combinations.
Probably there is something more interesting than this in Knuth.
i found this code here, and it gives me exactly what i need. you just have to create a table with numbers from 1-100. instructions at the link below
enter link description here
thank you everyone
Public Sub buildquery(strN As String, K As Integer)
Dim qd As DAO.QueryDef
Dim intI As Integer
Dim strsql As String
Dim strSelect As String
Dim strFrom As String
Dim strWhere As String
Set qd = CurrentDb.QueryDefs("QN")
qd.sql = "SELECT N FROM tblN WHERE N IN (" & strN & ")"
Set qd = Nothing
strSelect = "SELECT QN.N "
strFrom = "FROM QN "
strWhere = "WHERE QN_1.N > QN.N "
For intI = 1 To K - 1
strSelect = strSelect & ", QN_" & intI & ".N AS N" & intI & " "
strFrom = strFrom & ", QN AS QN_" & intI & " "
If intI < K - 1 Then
strWhere = strWhere & " AND QN_" & intI + 1 & ".N > QN_" & intI & ".N "
End If
Next
strsql = strSelect & " INTO tblCombinations " & strFrom & strWhere
DoCmd.SetWarnings False
DoCmd.RunSQL strsql
DoCmd.SetWarnings True
End Sub
then test
Public Sub testbuildquery()
buildquery "1,2,3,4,5,6,7", 3
End Sub