How can I create the "Hammock Task" with lags? - project

I need to create some tasks that have no constant duration, start and finish date. According to my researches online, the all need is "Hammock Task".
Lets say I have a task named T1 and have 2 milestones named M1 and M2. I want to set the start date of T1 as the date of M1 with 1 month delay and set the finish date of T1 as date of M2 with 2 months delay. The start and finish dates of T1 depend on M1 and M2.
I copied the dates of M1 and M2 and "Paste Special -> Paste Link" to T1. It works well until I add some lags to task with predecessors. The problem is after these steps, the duration of T1 changes all by itself. I mean that increases/decreases without any control even I don't touch mouse or keyboard. It just updates the duration every 5 - 10 seconds.

You almost had the solution. The trick is that the hammock task, T1, should not have any predecessors or successors. To get the lags you need, create new dummy lag tasks and paste-link the dates of those tasks.
In this example, Lag1 is a task with a 30-day elapsed duration (e.g. calendar days) that happens after the M1 milestone task and Lag2 is a task with a 60-day elapsed duration that happens after the M2 milestone task. This gives us the needed dates for the hammock task, T1. Paste-link the Finish date of Lag1 to the Start date of T1 and paste-link the Finish date of Lag2 to the Finish date of T1.
Now by changing either of the green cells, the duration of the hammock task (blue cell) updates automatically. (Note that T1 has no predecessors or successor--yellow cells).
Reference: support.office.com/en-us/article/prj-how-to-build-a-hammock-task
Note: When using OLE links, it is helpful to insert the Linked Fields field to see which tasks have a link; unfortunately there is no direct way to know which fields are linked. Also, edit the ribbon to add the Edit Links button which displays this dialog box.

Related

Laravel where clause based on conditions from value in database

I am building an event reminder page where people can set a reminder for certain events. There is an option for the user to set the amount of time before they need to be notified. It is stored in notification_time and notification_unit. notification_time keeps track of the time before they want to be notified and notification_unit keeps track of the PHP date format in which they selected the time, eg. i for minutes, H for hours.
Eg. notification_time - 2 and notification_unit - H means they need to be notified 2 hours before.
I have Cron jobs running in the background for handling the notification. This function is being hit once every minute.
Reminder::where(function ($query) {
$query->where('event_time', '>=', now()->subMinutes(Carbon::createFromFormat('i', 60)->diffInMinutes() - 1)->format('H:i:s'));
$query->where('event_time', '<=', now()->subMinutes(Carbon::createFromFormat('i', 60)->diffInMinutes())->format('H:i:s'));
})
In this function, I am hard coding the 'i', 60 while it should be fetched from the database. event_time is also part of the same table
The table looks something like this -
id event_time ... notification_unit notification_time created_at updated_at
Is there any way to solve this issue? Is it possible to do the same logic with SQL instead?
A direct answer to this question is not possible. I found 2 ways to resolve my issue.
First solution
Mysql has DATEDIFF and DATE_SUB to get timestamp difference and subtract certain intervals from a timestamp. In my case, the function runs every minute. To use them, I have to refactor my database to store the time and unit in seconds in the database. Then do the calculation. I chose not to use this way because both operations are a bit heavy on the server-side since I am running the function every minute.
Second Solution
This is the solution that I personally did in my case. Here I did the calculations while storing it in the database. Meaning? Let me explain. I created a new table notification_settings which is linked to the reminder (one-one relation). The table looks like this
id, unit, time, notify_at, repeating, created_at, updated_at
The unit and time columns are only used while displaying the reminder. What I did is, I calculated when to be notified in the notify_at column. So in the event scheduler, I need to check for the reminders at present (since I am running it every minute). The repeating column is there to keep track of whether the reminder is repeating or not. If it is repeating I re-calculate the notify_at column at the time of scheduling. Once the user is notified notify_at is set to null.

adding times to autofill a field VBA MSAccess

I am making a booking system on MSAccess using VBA. On my form I have fields for creating a new booking which is then to be added to a database on SQL server. I have a combo box set up to allow the user to select and activity and it then fills out the ID of the activity and the duration of the activity. This duration is a number 1 or 2 or 3 etc for how many hours the activity takes.
However my question relates to calculating a finish time for the user. I wish the finish time textbox to be auto filled out when the user selects a start time from a list of times for example, 9:00:00 (To match the format the times are stored on the sql server) and having selected an activity by adding these together. So far I have tried something like this.
Me.txtFinishTime.Text = Me.cmbStartTime.Value + Me.txtDuration.Value
It could be:
Me!txtFinishTime.Value = DateAdd("h", Me!txtDuration.Value, CDate(Me!cmbStartTime.Value))

Access Queries Over Date Range

I have an access query that will run to calculate the total activity in a location at a specified time. Is there a way to run this over a range of dates and return the results using SQL or should I write a form to run the query various with dates from code?
To make matters slightly more complicated, the query is also dealing with radioactive decay, correcting each item to its current activity at the time requested - although this can probably be ignored for testing.
Finally, on a slightly unrelated note, items and arrive and leave a location at any time, but it is unfeasible to have data points for each second of every day, so I am using three hour intervals as a compromise - as radioactive decay follows an equation, anyone have a better way of doing this (so that data is plotted as soon as an item arrives, otherwise the decay from the arrival time and plotted interval can effect my result a lot) or is this the best I am likely to manage?
Current SQL for single date:
SELECT FORMAT(SUM(Items.Activity*(Exp(-(0.693*(dDate-Items.MeasuredOn)/Nuclides.HalfLife)))), '#,##0.00') AS CurrentActivity
FROM Nuclides INNER JOIN ((Locations INNER JOIN (Items INNER JOIN ItemLocations ON Items.ItemID = ItemLocations.ItemID) ON Locations.LocationID = ItemLocations.LocationID) INNER JOIN LocationLimits ON Locations.LocationID = LocationLimits.LocationID) ON (Nuclides.Nuclide = Items.Nuclide) AND (Nuclides.Nuclide = LocationLimits.Nuclide)
WHERE (((ItemLocations.LocationID)=lLocationID) AND ((ItemLocations.RecieptDate)<dDate) AND ((ItemLocations.DisposalDate)>dDate Or (ItemLocations.DisposalDate) Is Null));
Could no figure out how to solve in the way I initially imagined, so solved as follows instead:
User inputs a date range for the time period they want to view data for.
One query to return single list of all dates when an event happened (date item added, date item removed)
Using set time intervals (now one hour) activity calculated at the time until an event time is reached. At event time activity is calculated for half a second before the event occurred and the time of the event itself. We then continue with our hour intervals until the next event.
After final event keep calculating at the interval until the end time is reached.
This works quickly enough to not be a problem for the user, and the graph is as smooth as it needs to be. FYI activity is also calculated half a second before events to give a vertical slope on the line, otherwise it will be slanted from the previous point (potentially an hour or more of time).

Qlikview line chart with multiple expressions over time period dimension

I am new to Qlikview and after several failed attempts I have to ask for some guidance regarding charts in Qlikview. I want to create Line chart which will have:
One dimension – time period of one month broke down by days in it
One expression – Number of created tasks per day
Second expression – Number of closed tasks per day
Third expression – Number of open tasks per day
This is very basic example and I couldn’t find solution for this, and to be honest I think I don’t understand how I should setup my time period dimension and expression. Each time when I try to introduce more then one expression things go south. Maybe its because I have multiple dates or my dimension is wrong.
Here is my simple data:
http://pastebin.com/Lv0CFQPm
I have been reading about helper tables like Master Callendar or “Date Island” but I couldn’t grasp it. I have tried to follow guide from here: https://community.qlik.com/docs/DOC-8642 but that only worked for one date (for me at least).
How should I setup dimension and expression on my chart, so I can count the ID field if Created Date matches one from dimension and Status is appropriate?
I have personal edition so I am unable to open qwv files from other authors.
Thank you in advance, kind regards!
My solution to this would be to change from a single line per Call with associated dates to a concatenated list of Call Events with a single date each. i.e. each Call will have a creation event and a resolution event. This is how I achieve that. (I turned your data into a spreadsheet but the concept is the same for any data source.)
Calls:
LOAD Type,
Id,
Priority,
'New' as Status,
date(floor(Created)) as [Date],
time(Created) as [Time]
FROM
[Calls.xlsx]
(ooxml, embedded labels, table is Sheet1) where Created>0;
LOAD Type,
Id,
Priority,
Status,
date(floor(Resolved)) as [Date],
time(Resolved) as [Time]
FROM
[Calls.xlsx]
(ooxml, embedded labels, table is Sheet1) where Resolved>0;
Key concepts here are allowing QlikView's auto-conatenate to do it's job by making the field-names of both load statements exactly the same, including capitalisation. The second is splitting the timestamp into a Date and a time. This allows you to have a dimension of Date only and group the events for the day. (In big data sets the resource saving is also significant.) The third is creating the dummy 'New' status for each event on the day of it's creation date.
With just this data and these expressions
Created = count(if(Status='New',Id))
Resolved = count(if(Status='Resolved',Id))
and then
Created-Resolved
all with full accumulation ticked for Open (to give you a running total rather than a daily total which might go negative and look odd) you could draw this graph.
For extra completeness you could add this to the code section to fill up your dates and create the Master Calendar you spoke of. There are many other ways of achieving this
MINMAX:
load floor(num(min([Date]))) as MINTRANS,
floor(num(max([Date]))) as MAXTRANS
Resident Calls;
let zDateMin=FieldValue('MINTRANS',1);
let zDateMax=FieldValue('MAXTRANS',1);
//complete calendar
Dates:
LOAD
Date($(zDateMin) + IterNo() - 1, '$(DateFormat)') as [Date]
AUTOGENERATE 1
WHILE $(zDateMin)+IterNo()-1<= $(zDateMax);
Then you could draw this chart. Don't forget to turn Suppress Zero Values on the Presentation tab off.
But my suggestion would be to use a combo rather than line chart so that the calls per day are shown as discrete buckets (Bars) but the running total of Open calls is a line

Storing attendance records in the database

I found a similar question asked previously (School attendance database)
I have to deal with these additional conditions.
Total number of users recording attendance would be 100,000.
Each user will have swipe-in swipe-out entry.
A user may do multiple swipe-in swipe-out incase s/he is not sure data was captured.
A record of 1 year attendance has to be maintained which can be access by the user.
The basic table i thought was with following entries.
UserID - numeric value
Date
Swipe in time
Swipe out-time.
If this is the table then approx number of rows in database would be = 100,000 x 250(working days in yr) = 25,000,000 in ideal situation. Now if user duplicate either swipe-in or swipe-out rows will add up. Say 1/3 of employee do this to ensure attendance is marked. so additional rows 8,333,333 totalling to 33,333,333 approx.
One of the issues would be when a user swipes-in twice but swipes out only once. Then i need to have null value in the second swipe-in or fill the same value in the swipe-out field. This would add up the additional rows mentioned.
The other option i thought was to run a background task every day to clean the double user entry. Say user swipes in at 8.00 A.M and then 8.10 A.M so the system removes the 8.10 A.M entry at the end of the day.First in last out time basis.
However, i prob i forsee is. If say user stays overnight in office working and swipes maybe 2.00 A.M. The swipe data would be
Swipe in - 1-Jan-10 - 8.00 A.M.
Swipe out - 2-Jan-10 - 2.00 A.M.
Swipe in - 2 Jan-10 - 1.00 P.M. (he comes back to office again same day - work pressure :))
Swipe out - 2 Jan-10 - 10.00 P.M.
How to handle this?
My questions are:
1. Is the number of rows listed acceptable to databases like mysql, postgresql without delaying too much of retrival time? I would be interested more in opensource db performance.
2. Is there a better way to format the table than this?
The simple answer is that you log swipes rather than days and then post-process the data to achieve the required tracking - even without your example there are the more more basic cases of "going out for lunch" or other reasons to go off site that require more than one arrival and departure per day.
Whatever you do you're going to have issues with multiple swipes - people being "people" you're going to struggle with edge cases i.e. where a user behaves in an odd fashion for whatever reason (usually quite innocent...).
Here's a little normalization:
UserTable:
UserID
FirstName
LastName
Email
WhateverOtherFields
UserCreated [datetime]
LastActivityDateTime [datetime]
AttendanceTable:
AttendanceID
UserID
EventID
SwipeIn [datetime]
SwipeOut [datetime]
EventTable:
EventID
EventName
EventLocation
EventStart [datetime]
EventEnd [datetime]
With a layout like this you can keep multiple attendances on file even for the same day. You would allow user to SwipeIn to begin an Attendance per-se, and would keep that attendance open until user SwipeOut. Maybe also give the system a flushing process to allow you to close out those attendees that never got to SwipeOut. By adding something like an events table to attach to the attendance table you would allow for tracking of events and the like. You can totally go all out or KISS.
Hope this helps!
I don't see any issues with the no. of rows. Many applications commonly have such amount of data. For your questions below is my opinion:
1) You need to consider official working hours say 9AM to 6PM i.e 9 hrs daily. If a user overstays after midnight the remaining amount of time after midnight should be added to next day's attendance.
Swipe in - 1-Jan-10 - 8.00 A.M. + Swipe out - 2-Jan-10 - 2.00 A.M.
= 16hrs in 1 Jan-10 + 2hrs in 2 Jan-10
Swipe in - 2 Jan-10 - 1.00 P.M. + Swipe out - 2 Jan-10 - 10.00 P.M.
= 9hrs in 2 Jan-10
So your total is 16hrs in 1 Jan-10 and 11 hrs in 2 Jan-10.
One more thing you can add in your table is column "Hours logged". Not very useful but sometimes helpful in pulling the report. You can add value to this column only for swipe out entries which will not be cleaned out i.e last out entry.
Think about the below steps:
Make a logical setting like if the difference between two logins is more than the daily working hours then the application can understand that the user forgot to log out.
Add a flag in the corrupted recede (which have login without logout or multi same action in same day or ...) which you got from the card reader and mack sub form to modify it manually by the attendance manager or the person in-charge.
Table design
attendance table
a) attId int incr
empid
[login] (datetime)
[LogOut] (datetime)
[is Complete] (bit) <-- this flag Depends on the logical setting you make and show it to the manager to modify it
'-----------------------
I think there is a way to manage this case automatically by the system. The human touch must help.