I have extremely limited knowledge of MS Access, but I'm trying to create an AfterInsert event.
Here's the table (myTable) context-- The table is going to be a list of goals for different departments, and have an Active column. This will allow a department to change it's #1 goal by creating a new record, setting it as goal = 1, and then updating the old record with goal = 1 to Active = False. We want a running history of the goals and priorities (goal number).
AutoID Dept Goal# Goal Active
00001 A 1 My first goal True
00002 A 2 My second goal True
00003 A 3 My third goal True
Now, I want to add a new record because we've changed goal one.
00004 A 1 My new first goal True
And what it should do after adding this new record is set old goal 1 Active = False.
AutoID Dept Goal# Goal Active
00001 A 1 My first goal False
00002 A 2 My second goal True
00003 A 3 My third goal True
00004 A 1 My new first goal True
I've been trying to adapt this AfterInsert format
LookupRecord In qryDMTermQuery
Where Condition = [EmployeeID]=[tblTerminations].[EmployeeID]
Alias
EditRecord
Alias
Comment Block: Set Active field to False
SetField
Name: [qryDMTermQuery].[Active]
Value: False
End EditRecord
This is my adaptation:
LookupRecord In myTable
Where Condition = [dept]=[myTable].[dept]
AND [Goal#] = [myTable].[Goal#]
AND [AutoID] != [myTable].[AutoID]
Alias
EditRecord
Alias
Comment Block: Set Active field to False
SetField
Name: [myTable].[Active]
Value: False
End EditRecord
Does this make sense/is this doing what I'm hoping for?
You were almost there. There is no need for [AutoID] != [myTable].[AutoID] as the new ID generated obviously won't match the existing. Alternatively you can use [AutoID] <> [myTable].[AutoID]
Related
Im not sure why I cant find this online but I simply want to tell a query to have a new column which is the same thing for every row.
So something like this:
ID Pollo
001 True
002 False
003 True
004 False
005 True
And I wanna make it this where I add a variable called Tag and it is strictly the word "Mark" for every row:
ID Pollo Tag
001 True Mark
002 False Mark
003 True Mark
004 False Mark
005 True Mark
You can add a constant expression as a column in a query's select-list, and an expression can be a simple value:
SELECT ID, Pollo, 'Mark' AS Tag
FROM mytable;
Since this value is a constant, it will be the same on every row returned by the query.
You should assign the column an alias by using the AS keyword. This becomes the header for the column.
The data type for the column is implied by the expression. In this case, it's a varchar.
If you want to add the data to the table:
alter table yourmysterytablename add column Tag varchar(desiredmaximumlength);
update yourmysterytablename set Tag='Mark';
If you just want to add it to your select results:
select ID, Pollo, 'Mark' as Tag
from yourmysterytablename
where ...
Check following section is model related sections :
ALL_STATUS = ['approved', 'pending', 'processing', 'declined', 'rejected']
#agent.rb
has_many :reports
has_many :assessments, through: :reports
#report.rb
has_many :assessments
belongs_to :agent
#assessment.rb
belongs_to :agent
Those are my sample records in DB.
#agent
id name
1 Alex
2 Justin
3 Clark
4 Mike
#reports
id agent_id status
1 1 approved
2 1 pending
3 1 processing
4 1 rejected
#assessment
id report_id agent_id status
1 1 1 approved
2 3 1 processing
3 2 1 pending
4 4 1 rejected
Desc:
once we create reports those are getting converted to assessment
record.
Here reports submitted by agent#Alex(user_id: 1) has been added for assessment.
I want to find out those UserIDs whose all assessments are not Yet added / Reject those user_ids whose reports are already added to
assessment List?
So here output will be only [2,3,4]. (those ids might have reports record but may not have any assessments)
I am using following code to get those agent ids.
eligible_agents = []
result = Agent.joins(:reports, :assessments)
result.each do |agent|
if(agent.reports.pluck(:status).count !=agent.assessments.pluck(:status).count)
eligible_agents.push agent.id
end
end
Here the problem is clearly visible, if number of reports/assessments grows then query present inside if condition is going to run multiple times.
What better solution we can have here ?
The following will return any Agent who does not have an Assessment:
Agent.where.not(id: Assessment.all.pluck(:agent_id))
Is this what you were looking for?
If you need just the Agent ids:
Agent.where.not(id: Assessment.all.pluck(:agent_id)).pluck(:id)
Instead of going though Agent you want to get all reports that don't have associated assessment. Then grab agent_ids from that list. I think joins does an inner join by default, so you need to specify left join condition and filter things that are missing assessments. Then you can just pluck(:agent_id) out of that.
I am editing someone elses database who used the "set type" to store the data.
There is one row that stores all the "profile data" for the user and then in that row is multiple "sets" that have been selected by the user preferences as numbers.
Example of one row in database OLD:
profilevalue_id = 1
ProfileUser_id = 120
profilevalue10 = hockey
profilevalue50 = 2,4,5,6,19 (the set)
I need to copy this to a new database and 'expand' that set into individual items like
Example of one row in new database NEW:
item_id = 120
field_id = 10
value = hockey
Example of the set row in the new database NEW:
item_id = 120
field_id = 50
value = 2
The next number in the set as an individual row NEW:
item_id = 120
field_id = 50
value = 4
and so on... I've found information about break sets via string, but not what i'm looking for here... any advice on where to start looking?
Thank you.
I am trying to determine the best method for how to handle this query using Access 2013. I have a clients table that contains the following:
clientID fName lName admissionDate dischargeDate
1 John Doe 05/06/2014 06/27/2014
2 Jane Doe 04/24/2014 05/15/2014
3 Steven Smith 05/15/2014 NULL/Empty
4 Chris Davis 06/12/2014 NULL/Empty
Then there is a WeeklyProgressNotes table that is there for the person that is responsible for auditing the clients charts. It does not contain the actual weeklyprogressnotes, it only contains a Yes/No field and a date field for the date the weeklyprogressnote was completed. Like below:
noteID completed dateCompleted clientID
1 yes 05/08/2014 1
2 yes 05/14/2014 1
3 yes 04/25/2014 2
I am creating a form that the auditor can open to determine what weeks she needs to check for each client to see if they have their weeklyprogressnotes completed that week. The weeks run Mon - Sun and there will be no record in the WeeklyProgressNotes table if she has not yet checked and confirmed for that week. So the form would basically look like this:
fName lName week completed date clientID(hidden)
John Doe 5/19/14-5/25/14 Checkbox Null 1
John Doe 5/26/14-6/1/14 Checkbox Null 1
John Doe 6/2/14-6/8/14 Checkbox Null 1
John Doe 6/9/14-6/15/14 Checkbox Null 1
John Doe 6/16/14-6/22/14 Checkbox Null 1
John Doe 6/23/14-6/29/14 Checkbox Null 1
Jane Doe 4/28/14-5/4/14 Checkbox Null 2
and so on.......
I have thought about creating an SQL statement to select all of the clients and then creating a function that determines their admission date within the specific week and their discharge date withing the specific week and then create a loop with another SQL statement with a BETWEEN clause for all the weeks and determine if there is an entry in the WeeklyProgressNotes table or not. If not then I would display out the above info. I'm not sure if there is an easier, less search intensive way of doing it. Maybe an SQL query that can cut done on some of the looping.
The way I would address this problem, is to create a new table. Since you want to split up date time between addmission and discharge date into multiple rows, I think it would be best to split the client in multiple records in a table.
The following code creates a recordset based on your basic clients table. Afterwards it creates your temporary table (Here populated by only 2 fields due to a lack of time). When you loop through the recordset of your original table, you hold on each row and split the time between the addmission and dischargedate in blocks of one week.
Afterwards, once you have populated the table, it is easy to create a simple query based on this table and the table with the weeklyprogressnotes.
I hope my explanation was sufficient and please note that I have not tested the code yet. It will most likely require some tweaking on your behalf. Perhaps I can look at it later on if I've got some more time on my hands.
Sub showrecords()
Dim gvweek As String
Dim rs As Recordset
Dim rstemp As Recordset
Dim tdfNew As TableDef
gvweek = ""
Set tdfNew = CurrentDb.CreateTableDef("Tbl_Temporary")
With tdfNew
.Fields.Append .CreateField("fName", dbText)
.Fields.Append .CreateField("week", dbText)
End With
Set rs = CurrentDb.OpenRecordset("Clients")
With rs
Do Until .EOF
.MoveFirst
Do Until DateAdd("dd", 7, ![admissionDate]) > ![dischargeDate]
gvweek = ![admissionDate] & " - " & DateAdd("dd", 7, ![admissionDate])
Set rstemp = CurrentDb.OpenRecordset("Tbl_Temporary")
With rstemp
.AddNew
![fName] = rs![fName]
![week] = gvweek
.Update
End With
rstemp.Close
Set rstemp = Nothing
Loop
gvweek = ""
.MoveNext
Loop
End With
rs.Close
Set rs = Nothing
DoCmd.DeleteObject acTable, "Tbl_Temporary"
End Sub
I am having troubles using the aggregate functions when using features like group by in a query. Instead of my aggregate functions applying to the entire query recordset, they only apply to select groups determined by the nature of the query. For example:
Person Date Able
-----------------------------
A 21/05/13 0
B 21/05/13 -1
C 21/05/13 -1
D 21/05/13 0
(grouped by Person, Date, Able)
When applying aggregate functions:
Person Date Able Max(Able) Min(Date)
----------------------------------------------------
A 21/05/13 0 0 21/05/13
B 22/05/13 -1 -1 22/05/13
C 23/05/13 -1 -1 23/05/13
D 24/05/13 0 0 24/05/13
The aggregate functions are made entirely redundant unless the data is completely ungrouped. So far, I have been getting around it using:
1) Using another query to reference the initial query and determine the true aggregate values.
2) Have the form call this second query using the d functions (dlookup,dcount etc.)
In my particular scenario, I have a list (very similar to above) that needs to be presented in a certain order (ranked based on ID). However, I am using an expression in the query to define a different type of ranking. The idea is to show (using conditional formatting) the first record in this new rank. Illustrated below
Person Date ID CalculatedRank
--------------------------------------------
A 21/05/13 1 4
B 21/05/13 2 2
C 21/05/13 3 3
D 21/05/13 4 1
Ideally I would like to have another column that determines which one is first which could be easily acheived by:
first: [CalculatedRank] = Min( [CalculatedRank] )
But as described above, Min() is not giving me 1, it is giving me it on a per row basis (the minimimum isn't always 1 so I can't set this arbitrarily).
Right now I am using a separate query to reference this first query and I sort that based on the calculated rank. Conditional formatting can then use dlookup to determine whether it is first or not from the second query. However, everytime the form refreshes, or a requery is called, every single row's conditional formatting triggers another dlookup, which then references the first query recalculating the new rank, for every row!
As you can imagine, the delay is noticeable causing the cursor to be idle for >5seconds. I am not too sure about the internal mechanisms of access, but using the inbuilt debugger, a requery on a recordset of 4 rows caused my CalculateRank() function to be called 12 times, purely through the conditional formatting calling the second query.
In summary, I have pretty much narrowed it down to requiring a separate query (and therefore dlookup) to properly use the aggregate functions. If I was able to keep everything in one query, the conditional formatting wouldn't need to use dlookup on another query to determine its status.
I am sure I am not the only one that has had problems with this and was wondering if any solutions exist where I can avoid all the stacked querying.
As always, any help is much appreciated!
Wow, I see what you mean! For my table [Table1]
Person Date ID
------ ---------- --
A 2013-05-21 1
B 2013-05-21 2
C 2013-05-21 3
D 2013-05-21 4
and my query [qryTable1Ranked]
SELECT Table1.*, CalculateRank([ID]) AS CalculatedRank
FROM Table1;
which uses the following function in a standard VBA Module
Public Function CalculateRank(ID As Long) As Long
Dim r As Long
Select Case ID
Case 1
r = 4
Case 4
r = 1
Case Else
r = ID
End Select
CalculateRank = r
Debug.Print "x"
End Function
and returns
Person Date ID CalculatedRank
------ ---------- -- --------------
A 2013-05-21 1 4
B 2013-05-21 2 2
C 2013-05-21 3 3
D 2013-05-21 4 1
when I just double-click the query to open it in Datasheet View my ranking function gets called 4 times, once for each row.
If I create a continuous form based on that query and open the form my function gets called 4 times. Then if I add conditional formatting on the [CalculatedRank] text box using Value = DMin("CalculatedRank", "qryTable1Ranked") then my function gets called 32 times!
I found that I can cut that by half (to 16 times) if I add an invisible unbound textbox named [txtMinCalculatedRank], use the following code behind the form...
Option Compare Database
Option Explicit
Private Sub Form_Load()
UpdateMinCalculatedRank
End Sub
Private Sub UpdateMinCalculatedRank()
Me.txtMinCalculatedRank.Value = DMin("CalculatedRank", "qryTable1Ranked")
End Sub
...and change the Conditional Formatting rule to Value = [txtMinCalculatedRank].
I found that I could cut that by half again (to 8 times) if I changed the Record Source of the Form from qryTable1Ranked to Table1 (the base table) and changed the Control Source of the [CalculatedRank] text box to =CalculateRank([ID]) (still using the tricks from the previous tweak).
I think that's probably as good as it gets without going so far as to create a temporary table, or persisting the CalculatedRank (and perhaps an "IsMin" flag) in the base table.