I have a table that has auto-calculated fields for who (name) and when (date) the row was last changed, using the normal FileMaker field definitions and a protected field.
However, I have one use case where I copy data into this table, from a source that also has these entries, and I want to copy them as well. But when my script copies the data, it triggers the auto-calculation, and in the end, my "changed at" is set to the current time and "changed by" to the current user. I want to retain whatever my external source has in these fields.
How can I temporarily disable the auto-calculation for these fields in FileMaker, so that for the duration of my script, they act as normal fields and simply take the data I enter?
Change your auto-entered modification fields as follows
Switch to auto-enter Calculated value
Switch 'Do not replace existing value of field (if any)' off
Then set the auto-enter calculation to something like the following
Let ( trigger = GetField ( "" ) ; If ( $$SilentSync > 0 ; Self ; Get ( CurrentDate ) ) )
You'll need to change the Get ( CurrentDate ) to whatever is appropriate for that field, and you'll need to do this for all modification fields in every table.
After this these fields will work as normal during day-to-day editing etc.
When setting data during your sync you can use the following at the beginning of the sync process
Set Variable [$$SilentSync: 1]
Then clear $$SilentSync at the end of the sync process
Set Variable [$$SilentSync: ""]
Related
I have an excel sheet with many tabs. Say one is called wsMain and the other is called wsDate.
In my data flow transformation I am able to successfully load the data from wsMain to my table.
Now I have to update this transformation where I have to fetch the maximum date from the worksheet wsDate and only load data from wsMain where the date is less than on equal to the maximum date in wsDate (that is the only column available).
So for I have figured out that I need to create a new Excel connection manager to read the data from wsDate and I have used the Aggregate transformatioin to get the maximum date.
Now the question is how do I use this date to restrict the rows coming from wsMain?
I understand from the link below that you can store the value in a variable but what do I do next?:
SSIS set result set from data flow to variable
I have tried using a merge join but not sure if I am doing it right.
Here is what it looks like now:
I could not achieve the above but would be interested to know if that is possible. As a work around I have created a separate dataflow where I have stored the valued in a variable and then used the variable in the conditional split to filter the required rows:
Here is a step by step guide I followed to write the variable:
https://www.proteanit.com/2008/12/11/ssis-writing-to-a-package-variable-in-a-dataflow/
You can obtain the maximum value of the wsDate column first, this use this as a filter to avoid introducing unnecessary records into the data flow which which would be discarded by the Conditional Split. An overview of this process is below. I'd also recommend confirming the data types for all columns involved.
Create an SSIS DateTime variable and name this something descriptive such as MaxDate.
Create a Data Flow Task before the current one with an Excel Source component. Use the SQL command option for the Data Access Mode and enter a SQL statement to return the max value of the wsDate column. In the following example ExcelSource is the name of the sheet that you're pulling from. I'd suggested confirming the query with the Preview button on the Excel Source as well.
Add a Script Component (not Task) after the Excel Source. Add the MaxDate variable in the ReadWriteVariables field on the main page of the Script Component. On the Inputs and Outputs pane add the output column from the Excel Source as an Input Column with the ReadOnly usage Type. Example C# code for this is below. Note that variables can only be written to in the PostExecute method. The Input0_ProcessInputRow method is called once for each row that passes through, however there will only be the single row in this case. On the following code MaxExcelDate is the name of the output column from the Excel Source.
On the Excel Source component in the Data Flow Task where the records are imported from Excel, change the Data Access Mode to SQL command and enter a SQL statement to return records that have a date less than or equal to the maximum wsDate value. This is the last example and the ? is a placeholder for the parameter. After entering this SQL, click the Parameters button and select Parameter0 for the Parameters field, the MaxDate variable for Variables field, and a direction of Input. The Conditional Split can then be removed since these records will now be filtered out.
Excel MAX wsDate SELECT:
SELECT MAX(wsDate) AS MaxExcelDate FROM ExcelSource
C# Script Component:
DateTime maxDate;
public override void PostExecute()
{
base.PostExecute();
Variables.MaxDate = maxDate;
}
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
maxDate = Row.MaxExcelDate;
}
Excel Command with Date Filter:
SELECT
Column1,
Column2,
Column3
FROM ExcelSheet
WHERE DateColumn <= ?
Yes, it is possible. In the data flow, you will need to determine the max date, which you already have. Next, you will need to MERGE JOIN the two data flows on the date column. From there, you will feed it into a CONDITIONAL SPLIT and split where the date columns match [i.e., !ISNULL()] versus do not match [i.e., ISNULL()]. In your case, you only want the matches. The non-matches will be disregarded.
Note: if you use an INNER JOIN on the MERGE JOIN where there is only one date (i.e., MaxDate) to join on, then this will take care of the row filtering for you. You will not need a CONDITIONAL SPLIT.
Welcome to ETL.
Update
It is a real pain that SSIS's MERGE JOINs only perform joins on EQUAL operations as opposed to LESS THAN and GREATER THAN operations. You will need to separate the data flows.
Use a script component to scan the excel file for the MAX Date and assign that value to a package variable in SSIS. Alternatively, you can have a dates table in SQL Server and then use an Execute SQL Command in SSIS to retrieve the MAX Date from the table and assign that value to a package variable
Modify your existing data flow to remove the reading of the Excel date file completely. Then add a DERIVED COLUMN transformation and add a new column that is mapped to the package variable in SSIS that stores the MAX date. You can name the Derived Column Name 'MaxDate'
Add a conditional split transformation with the following CONDITION logic: [AsOfDt] <= [MaxDate]
Set the Output Name to Insert Records
Note: The CONDITIONAL SPLIT creates a new output data flow with restricted/filtered rows. It does not create a new column within the existing data flow. Think of this as a transposition of data flow output from column modification to row modification. Only those rows that match the condition will be sent to the output that you desire. I assume you only want to Insert these records, so I named it that. You can choose whatever naming convention you prefer
Note 2: Sorry for not making the Update my original answer - I haven't used the AGGREGATE transformation before so I was not aware that it restricts row output as opposed to reading a value in the data flow and then assigning it to a variable. That would be a terrific transformation for Microsoft to add to SSIS. It appears that the ROWCOUNT and SCRIPT COMPONENT transformations are the only ones that have the ability to set a package variable value within the data flow.
Big question: How can I make Access automatically fill in a cell in a form based on previously entered data?
I need to enter leave details for members of staff. I tend to enter these by date, and in one to two week chunks. Is there a way to have the next new record automatically fill in the date part of the record with the previously entered one?
Table structure
Staff: StaffID, Name
Absences: ID, StaffID, Dateaway, OtherDetails
I want it to automatically fill in DateAway with the entry of the row above it, or the previously entered row, as I will enter say 10 dates in a fortnight, but 50 entries over those dates. I enter them chronologically, and after the fact (So just defaulting to TODAY() won't work).
There's a shortcut Ctrl+' that does pretty much what I need, wondering if there's a way to do that with the generation of a new record.
You have to be careful with this. If your form is bound to a table/query, you're going to insert a junk record every time you're done with the form. However, if it's unbound you can do this using DMAX, in the After Insert event of the form.
Private Sub Form_AfterInsert()
txtDateaway.Text = DMax("Dateaway", "Absences", "StaffID = " & Me.txtStaffID)
End Sub
This is, of course, assuming your Dateaway field on your form is called txtDateaway and your StaffID field is called txtStaffID.
I want to use one parameter for date and another one for time in my reports as shown below.
Start Time [16/01/2012][12.00 am]
Can anyone help me regarding that?
Sure it is a multiple step process:
Set up a variable of TEXT as 'DATE' as the variable value and prompt
Set it's 'Default Values' in the left pane to be '1/16/2012'
Set up a variable of TEXT as 'TIME' as the variable value and prompt
Set it's 'Default Values' in the left pane to be '00:00'
Set up a dataset, 'AvailableDateTime' to combine the two into a legitimate datetime field:
SELECT CAST(#Date + ' ' + #Time AS DateTime) AS Datetime
Set up a third variable of DATETIME to be 'DATETIME' as the variable value and prompt.
Set up this variable to use 'AVAILABLE VALUES' on the left pane of properties to be 'Get values from a query'. Use the dataset from step 5.
You now have set up a separate field for data and time.
Further consideration to avoid user input error. You may wish to tie the first variables to be selectable ONLY FROM values you set in available values or from a query. The problem being if a user fat fingers the date or time it will not run as the system is only trying to combine two strings and make a datetime out of it. You may wish to list values directly from a query from the getgo.
EDIT FOR CHANGING FIRST TWO VARIABLES:
You may set the first variable as datetime which gives the end user a calendar.
You can set a second dataset up to get available times for an end user:
declare #time table ( tm int)
declare #cursor int = 0
while #cursor <= 23
Begin
insert into #time values (#cursor)
set #cursor += 1
End
select cast(CAST(tm as varchar) + ':00' as time) as HourOfTheDay
from #time
Setting your second variable to get values from a query that is made in step 2 directly above.
You should now be able to put the values together as above.
As I said in my comment, SSRS does not allow you to have separate parameters for Date and Time.
It has only one parameter Date/Time.
As I see you have two options.
Add a text parameter and consider that as time. You could then do
some validation depending on what tech you are using.
Another way to solve this would be creating a list of possible
values. You select Integer type, for instance and then create a list
of Available Values. (see images)
So we use FMP11 to do inventory management. I do price updates to our products 3 times a week and it would be nice to store our past cost values into a separate table for historical pricing. I know how I would go about doing most of it, but is it possible to create a new field that is labeled as today's date on the fly? So my headers would be labeled with that days date and the old pricing value from my other fields would be inserted.
It is a bad idea to create new fields for the purpose you're describing. Create additional records instead, and do your report going from top to bottom instead of left to right.
That said, if you want to do it, you can using FileMaker Server Advanced with JDBC and the ALTER TABLE command.
Create an new table (e.g. ArchivePricing) to hold the values you want to reference at a later date (e.g. ChangeDate, Price, Item, ItemID, etc.).
Create a new field in the current table called z|newprice - use this to type in your new pricing (you might do this on a list layout so you can easily change a bunch of prices).
Create a button that triggers a script that:
creates a new record in the new ArchivePricing table and inserts the ItemID (thus creating a link to the original table) - this can be done using script parameters or setting a variable)... the script continues.
uses the "set field" script step to insert info to this new record in the ArchivePricing table.
uses the Get (CurrentDate) function to insert the date into the ChangeDate field (thus capturing the date the change was made).
Before the script finishes be sure to use "set field" back in the original table to move the value in z|newprice field into your normal Price field. Do this at the end of the script and then commit record.
Ok... So. I have an interactive report in APEX that displays data about documents in our system. Our documents are supposed to be reviewed every two years and there is a column in the table that contains the date that the document should be next reviewed by. We want to visually indicate either in the cell that contains the date, or another cell in the row, when the date reaches certain benchmarks (i.e. When the date is within 6 months of the current date, 3 months, 2, 1 etc.)
What I need to hopefully do is to change the color of the text (or background) of a specific cell based on either the value of that cell or the value of another cell in the same row. There would need to be a process or some function that does some computation to determine the span between the sysdate and the date contained in the cell... It does not necessarily need to calculate when the page is loaded but a daily or weekly process or something would be good.
Is it possible to set up processes or triggers that execute daily without human interaction? I also have a need to use the same functionality for sending reminder emails about these upcoming deadlines. (i.e. when a document is 6 months out from needing to be reviewed an email would be sent out, at 3 months, 2, 1 etc.)
Example with hiredate on emp: i'm about to colour the cells that are > 11000. (sysdate-hiredate ranges from about 10k to 12k). You could use a field you calculate in the query, or one you filled in through some procedure, doesn't matter :)
select empno, ename, job, mgr, hiredate, sal, comm, deptno,
trunc((trunc(sysdate)-hiredate)) to_colour_or_not
from emp
You will need 2 dynamic actions to colour rows in reports: an onload action, and an after refresh. If you skip the after refresh, rows won't be coloured after for example pagination, due to partial page refreshing.
Dynamic action one: After refresh on the region:
True action:
$("td[headers='TO_COLOUR_OR_NOT']").each(function(){
alert($(this).text());
if(parseInt($(this).text()) > 11000){
$(this).css({"background-color":"red"});
};
});
Example of using one column as a condition to colour another column. Always be carefull with what you test and what you test it for! For example, the hiredate column is a date, be sure to treat it as such if necessary! Further caution too: if your date format is set as DD-MON-YYYY, then you'd have to do the mapping for month to number (JAN = 1, DEC = 12)! Maybe it is an option to change the date format for this column even...
$("td[headers='HIREDATE']").each(function(){
var i_date = $(this).text();
//date format = MM/DD/YYYY
//be carefull with date formats.
//in my case, i know my date format and know it won't change
//my code is far from a complete parse of possible date values!
var dMonth = i_date.substring(0, 2),
dDay = i_date.substring(3, 5),
dYear = i_date.substring(6);
var d = new Date(dYear, dMonth, dDay, 0, 0, 0, 0);
if(d.getFullYear() <= 1981){
//we are looping over TD elements. I want to colour the
//column ENAME in red when the condition is true for this row.
//so, $(this) = TD element we loop with. parent = TR element,
//then back to the children of the row
$(this).parent().children("td[headers='ENAME']").css({"background-color":"red"});
};
});
The second dynamic action: on load
As true action, use the same code as the true action for the refresh.
With the JS you can do whatever you want: you just need to know which cells you wish to paint. Use the [headers=''] to target the cells you'd like (jquery selectors).
Instead of the css(), you can use addClass for example, if that is more what you'd like.
Do mind: IRs come with built-in mouseover actions. This causes your painted cells not to show in their colour when there is a mouseover action. If you don't want this, you'd need another dynamic action for the mouseover/mouseleave events, and target those cells necessary.
As for scheduled jobs: check out DBMS_JOBS.
In an Interactive Report, you also can define REPORTS ( with HIGHLIGHTS), which will do the trick for you.
Choose button ACTIONS, Then FORMAT (on Pop-up) and the HIGHLIGHT
In HighLight you can give a Name, Type (Row or Cell), Background and Text Colour, and the COLUMN on which you want an OPERATOR and an EXPRESSION.
You Apply the Highlight (Make Several Highlights /other-name when you need more than one colour-highlight depending on your EXPRESSION-s).
Together with the most important Filters then SAVE it as a Report (First Primary).
After having defined the Primary Report you can take this as the basis-report. Make some other Reports (and save them) with other filters, but with the same Highlights as the Primary Report).
Have FUN with it.