Create Auto Repeated Records by Time - vba

I just new in access, and I have to face up the DB everyday. In this case, I create a form to record scedule of planned maintenance (next I call it "PM") which has variaties divided of time by week, month and year. Every PM that has been created, it has an unique number of PM. The number is as follows : 162/PNT/PM/06/2020. The number was containing with : "unique number"/"PM's area"/"type of maintenance"/"month"/"year".
Then, is there a way to create records repeatly based on time or previous PM schedule with the same content?
For an example :
I create a monthly PM schedule which the number is 001/PNT/PM/01/2020 on 20-Jan-2020. When I press the save button (or copy schedule button), the record will copying (creating) to 20-Feb-2020 with changed PM's number to 002/PNT/PM/02/2020 automatically.
Thanks for anyone who wants to help me.

June is right. Use a table like this:
ID - Long
PNT - Short Text
PM - Short Text
StartDate - DateTime
and a query to assemble the code:
SELECT
Maintenance.ID,
Maintenance.PNT,
Maintenance.PM,
Maintenance.StartDate,
Format([ID],"000") & "/" & [PNT] & "/" & [PM] & "/" & Format([StartDate],"mm\/ddyy") AS Code
FROM
Maintenance;
Output:
Now, to create the next record, use:
NextID = ID + 1
NextDate = DateAdd("m", 1, StartDate)

Related

Updating Due Date based on Invoice Date and Vendor

I am using DocuWare Workflow Designer (uses SQL) to fill in the due date based on the invoice date and vendor name. In the code below I am trying to have it add 15 days to the invoice date if the vendor is "Hueber - Jones & Coontz" otherwise have the Due Date equal the Invoice Date. The code errors out currently and makes the Due Date equal todays date. I am not able to bring up where in the code its failing. Everything in brackets is references to predefined variables in DocuWare.
SELECT [DW_INVOICE_DATE] FROM [AP] WHERE IF [DW_VENDOR_NAME] = 'HUEBER - JONES & COONTZ' [DW_DUE_DATE] = DATEADD(DD,15,[DW_INVOICE_DATE] ELSE [DW_DUE_DATE] = [DW_INVOICE_DATE]
Thanks in advance.
I don't know how DocuWare works, it it's just simple SQL this is the command:
UPDATE [AP]
SET [DW_DUE_DATE] = (CASE
WHEN [DW_VENDOR_NAME] = 'HUEBER - JONES & COONTZ' THEN DATEADD(DD,15,[DW_INVOICE_DATE])
ELSE [DW_INVOICE_DATE]
END)

How to insert every Single date into table [duplicate]

hoping someone can help? I'm fairly new to Access 2016 and have been tasked with building a very simple booking system for our school's breakfast and after school clubs.
I have a table with a list of Children (primary key is ChildID), another table (CLUBS) lists the 5 clubs available, and a third table (BOOKINGS) connects the children to the clubs (ChildID, ClubID, DateRequested)
I have a simple form that enables me to select a child's name from a drop down box, then from a list choose a club, then enter the date required. This saves the record to the Bookings table.
This works fine, however to make it easier to use...I've added unbound Start and End Date fields in the form with a view to being able to quickly book a child in over a term..i.e. rather than having to add each day individually, I enter the child's name, choose a club and then enter start and end dates. Multiple records are created in the booking table with the Child ID, Club ID identical, but the DateRequested field varies.
We do need to store a record in the Bookings table for the child on each date so we can print a register for each day..as well as for invoicing/reporting.
From looking at VBA...I think I need to use the INSERT INTO command? Is the best way to do it? Also I need to make sure that dates within the range that are Sat/Sunday are ignored.
I'd really appreciate any guidance on this and pointers to which commands would work best...
This is where DAO shines. It is so much faster to run a loop adding records than calling a Insert Into multiple times.
Here is how:
Public Function PopulateBokings()
Dim rsBookings As DAO.Recordset
Dim NextDate As Date
Set rsBookings = CurrentDb.OpenRecordset("Select Top 1 * From Bookings")
NextDate = Me!StartDate.Value
While DateDiff("d", NextDate, Me!EndDate.Value) >= 0
If Weekday(NextDate, vbMonday) > 5 Then
' Skip Weekend.
Else
rsBookings.AddNew
rsBookings!ChildrenId.Value = Me!ChildrenId.Value
rsBookings!ClubsId.Value = Me!ClubId.Value
rsBookings!DateRequested.Value = NextDate
rsBookings.Update
End If
NextDate = DateAdd("d", 1, NextDate)
Wend
rsBookings.Close
Set rsBookings = Nothing
End Function
Paste the code into the code module of the form, adjust the field and control names to those of yours, and call the function from the Click event of a button.
Consider populating a separate DateRange table that holds all possible dates, like all of 2017. You can build such a table iteratively with dynamic SQL query calls in VBA. And only run this once.
Then, create a stored query that cross joins Children, Club, and DateRange with filters for all by form parameters. This returns all possible date ranges repeating same Child and Club for table append.
VBA
Public Sub PopulateTime()
Dim i As Integer, StartDate As Date
CurrentDb.Execute "CREATE TABLE DateRange (" _
& " [ID] AUTOINCREMENT PRIMARY KEY," _
& " [BookDate] DATETIME)", dbFailOnError
StartDate = DateSerial(2017, 1, 1)
For i = 0 To 364
CurrentDb.Execute "INSERT INTO DateRange ([BookDate])" _
& " VALUES (#" & DateAdd("d", i, StartDate) & "#);", dbFailOnError
Next i
End Sub
SQL
INSERT INTO Bookings (ChildID, ClubID, DateRequested)
SELECT c.ChildID, b.ClubID, d.BookDate
FROM Children c, Clubs b, DateRange d
WHERE c.ChildID = Forms!myformname!ChildID
AND b.ClubID = Forms!myformname!ClubID
AND d.BookDate BETWEEN Forms!myformname!StartDate
AND Forms!myformname!EndDate
You can use a sequence generator query to repeatedly insert rows into a table between two parameters.
For this example, the maximum number of days inserted is 999, but this can easily be increased to 9999 or even more.
Inspired by this answer by Gustav:
PARAMETERS [StartDate] DateTime, [EndDate] DateTime;
INSERT INTO MyTable(MyDateField)
SELECT DISTINCT [StartDate] - 1+ 100*Abs([Hundreds].[id] Mod 10) + 10*Abs([Tens].[id] Mod 10)+Abs([Ones].[id] Mod 10)+1
FROM MSysObjects As Ones, MSysObjects As Tens, MSysObjects As Hundreds
WHERE [StartDate] - 1+ 100*Abs([Hundreds].[id] Mod 10) + 10*Abs([Tens].[id] Mod 10)+Abs([Ones].[id] Mod 10)+1 Between [StartDate]-1 And [EndDate]
Performance won't be good, but there are multiple advantages using a non-VBA solution.

How to sum consecutive rows in Power Query

I have in Power Query a Column "% sum of all". I need to create a custom column "Sum Consecutive" that each row has as value the "% sum of all" of the current row + the value of "Sum Consecutive" of the previous row.
Current row situation
New Custom Column Expectation
You can see two images that show the current situation and the next situation I need in the Power Query.
Can you please help me find a code/command to create this new column like that?
Although there are similar solved questions in DAX, I still need to keep editing the file after that, so it should be performed in M language in power query.
Thank you!
Not sure how performant my approaches are. I would think both should be reasonably efficient as they only loop over each row in the table once (and "remember" the work done in the previous rows). However, maybe the conversion to records/list and then back to table is slow for large tables (I don't know).
Approach 1: Isolate the input column as a list, transform the list by cumulatively adding, put the transformed list back in the table as a new column.
let
someTable = Table.FromColumns({List.Repeat({0.0093}, 7) & List.Repeat({0.0086}, 7) & {0.0068, 0.0068}}, {"% of sum of all"}),
listToLoopOver = someTable[#"% of sum of all"],
cumulativeSum = List.Accumulate(List.Positions(listToLoopOver), {}, (listState, currentIndex) =>
let
numberToAdd = listToLoopOver{currentIndex},
sum = try listState{currentIndex - 1} + numberToAdd otherwise numberToAdd,
append = listState & {sum}
in
append
),
backToTable = Table.FromColumns(Table.ToColumns(someTable) & {cumulativeSum}, Table.ColumnNames(someTable) & {"Cumulative sum"})
in
backToTable
Approach 2: Convert the table to a list of records, loop over each record and add a new field (representing the new column) to each record, then convert the transformed list of records back into a table.
let
someTable = Table.FromColumns({List.Repeat({0.0093}, 7) & List.Repeat({0.0086}, 7) & {0.0068, 0.0068}}, {"% of sum of all"}),
listToLoopOver = Table.ToRecords(someTable),
cumulativeSum = List.Accumulate(List.Positions(listToLoopOver), {}, (listState, currentIndex) =>
let
numberToAdd = Record.Field(listToLoopOver{currentIndex}, "% of sum of all"),
sum = try listState{currentIndex - 1}[Cumulative sum] + numberToAdd otherwise numberToAdd, // 'try' should only be necessary for first item
recordToAdd = listToLoopOver{currentIndex} & [Cumulative sum = sum],
append = listState & {recordToAdd}
in
append
),
backToTable = Table.FromRecords(cumulativeSum)
in
backToTable
I couldn't find a function in the reference for M/Power Query that sums a list cumulatively.

Condition for Update vs insert

I have a table tblCosts which i display on an msaccess front end which enables users to add new entries as well as update existing ones. The table is structured as below.
ExpenseType Month Year Cost
Hardware June 2017 $500
Software July 2017 $300
Hardware Sept 2017 $150
I have an update and insert queries which work fine when run manually.
However I am having trouble differentiating the condition when to fire the query on the form. For example, if the record exists in the table, it should run the update query, if record does not exist, it should run the insert query.
For example if someone puts in
- Hardware Sept 2017 $120 it should update the 3rd entry from 150 to 120 but if someone puts in
- Furniture Sept 2017 $350 it should recognize that Furniture is not part of the DB and run the insert query. I have the update and insert queries but need help in identifying the condition when to run them.
The Update query I'm using is:
Update tblCosts
set tblCosts.Cost=[Forms]![frmCost]![txtCost]
where tblCosts.ExpenseType = [Forms]![frmCost]![txtExpType]
and tblCosts.Month = [Forms]![frmCost]![txtMonth]
and tblCosts.Year = [Forms]![frmCost]![txtYear]
The Insert query I'm using is:
Insert into tblCosts (ExpenseType , Month, Year, Cost)
Select [Forms]![frmCost]![txtExpType] as Exp1,
[Forms]![frmCost]![txtMonth] as Exp2,
[Forms]![frmCost]![txtYear] as Exp 3,
[Forms]![frmCost]![txtCost] as Exp 4
Need code (VBA or macro) behind a form that determines which action query to run. In VBA something like:
If DCount("*", "tablename", "ExpenseType='" & Me.cbxExpense & "' AND [Month]='" & Me.tbxMonth & "' AND [Year]=" & Me.tbxYear) = 0 Then
CurrentDb.Execute "INSERT INTO tablename (Expense, [Month], [Year], Cost) VALUES ('" & Me.cbxExpense & "', '" & Me.tbxMonth & "', " & Me.tbxYear & ", " & Me.tbxCost & ")"
Else
CurrentDb.Execute "UPDATE tablename SET Cost=" & Me.tbxCost & " WHERE Expense='" & Me.cbxExpense & "' AND [Month]='" & Me.tbxMonth & ", [Year]=" & Me.tbxYear
End If
Probably also want some validation code to make sure all four controls have data before executing queries.
The real trick is figuring out what event to put code into - the Cost AfterUpdate will work as long as the other fields have data entered first, otherwise the validation will fail and user will have to re-enter cost.
Could have code that doesn't make each control available until previous value is entered.
Month and Year are reserved words and should not use reserved words as names for anything.
Would be better to save month numbers instead of month names for sorting purposes.
Why updating a value which really should be a calculated aggregation of transaction records?

Find and copy the latest file

Our program is going to save PDFs to a network folder. I will then be copying the PDFs to a web server. There becomes a problem when a user saves/archives the same report more than once.
Example:
DAGH4 (002).PDF - Date Modified = 3/16/2016 10:10 AM
DAGH4 (001).PDF - Date Modified = 3/16/2016 9:00 AM
DAGH4.PDF - Date Modified = 3/16/2016 8:00 AM
DANYL (001).PDF - Date Modified = 3/16/2016 10:50 AM
DANYL.PDF - Date Modified = 3/16/2016 9:50 AM
Is there a way I could copy the latest version? I only want DAGH4 (002).PDF and DANYL (001).PDF to be copied. Or is there a way to rename and save the latest version?
Another thought
Using this code I check if the file exists and allow the user to click an thumbnail to open the associated PDF.
Dim pdf_path = Server.MapPath(String.Format("../Reports/{0}.pdf",
SerialNumber))
lblSerial.Visible = System.IO.File.Exists(pdf_path)
HyperLinkSerial.Visible = System.IO.File.Exists(pdf_path)
HyperLinkSerial.Text = "Inspection"
HyperLinkSerial.NavigateUrl = "../Reports/" & SerialNumber & ".PDF"
However, I need to only find and show the DAGH4 (002).PDF with the modified date 3/16/2016 10:10 AM
Is that possible using VB .NET?
To find the latest copy of each file, you could use LINQ to group by serial number, sort by modification date, and select the first item for each group. Note that this assumes that your "SerialNumber" is just letters and numbers (what the regex matches):
Dim latest As IEnumerable(Of String) =
From f In New DirectoryInfo(Server.MapPath("../Reports")).EnumerateFiles("*.PDF")
Let serialNumber = Regex.Match(f.Name, "^\w+").Value
Order By serialNumber Ascending, f.LastWriteTime Descending
Group By serialNumber Into Group
Select Group.First().f.FullName
latest will have the full path/name for the latest (based on modification date) file for each serial number.