use executeSQL() to populate portal in Filemaker - filemaker

I have a client with a Filemaker 16 app that uses an ODBC connection to a SQL Server DB. With Filemaker, everything I know about databases seems to be wrong. I have wrestled for 2 days with this and only ask as a last resort --- is it possible to populate a portal field with the results of a SQL query? I am trying to return unique records and exclude duplicates. Where would the executeSQL() call go? I thought perhaps in the Filter on the Portal, but that is not it. Sorry for the basic question.

A FileMaker portal will always show the records matching a given relationship in the Relationship graph. This set of records can be further constrained by the portal filter.
To achieve a list of unique items, you will need to create a calculation field in your related table that determines if the record is unique. This can be done in many ways, ExecuteSQL being one. You can then use this field as a predicate in the relationship itself or use it in the portal filter.

This is just one way to do it.
In the (shadow) table you want to display record from, create a calculation field that returned 1 if the record should be included and 0 if it should be omitted. It might be something like this:
Let (
[
_sql = List (
"SELECT id" ;
"FROM table" ;
"WHERE match_field = ?" ;
"ORDER BY id" ;
"FETCH FIRST 1 ROW ONLY"
) ;
_id = ExecuteSQL ( _sql ; "" ; "" ; match_field )
] ;
_id = id
)
Now in the table you want to show a portal from, create a global calculation field, ONE that returns 1 and then create a relationship between that table and the one you want to view a portal of using ONE and the SQL calc above as the match fields.
On a layout with a context into the LAYOUT_CONTEXT table above, you can create a portal into SHADOW_TABLE.

Related

Sails 1.0 Group By

Now that groupBy is deprecated, how can I mimic a SQL command like SELECT COUNT(*) FROM table GROUP BY xxx using the Waterline ORM ?
This page recommends using .sum() and .avg() but these methods are for number-type columns. Here I want to be able to count the rows of grouped columns, whatever type it is.
I think for specific groupBy query, you've got two choices.
The first one is a 2 step action.
1) Select all the unique element "group by field" you've got in the database.
2) Then count the record for each unique group by field element.
The second one is to use .sendNativeQuery() wich allow you to send a native SQL query to the datastore (you can use this only if you use a real SQL server and not the embedded Sails.JS database)
sendNativeQuery() Documentation

ms access form listbox changing whole field

I have created a form to update a query that that is in turn based on a master table containing information on a number of files. This master table is then related to several other tables in say for example a table called group_table, defining which group the file would belong to, which contains an ID field and the group_name. This is then related in a one-to-many relationship with the master table based on the group.ID and a field in the master table master_table.group and joined in the query the form is based on.
In the form I have designated a listbox control to update the group field of the query/master table. The contents available for selection in the list box were set based on the group_name field from the group_table table which is defined in the RowSouce section of the property sheet of the form.
So my issue is that when I try and update any records in the query using the listbox in the form, all of the records that are the same will get changed as well. E.g., changing a record in one row from "Group A" to "Group B" will change all the records containing "Group A" to "Group B" in the group field. So I was wondering if there is anything I can do to set it so only the specific record that I want to change gets changed.
When you are making the call to update the table you should make sure that you are using WHERE along with the primary key to make sure that you update that row only. An example would be a statement similar to the one below.
CurrentDb.Execute "UPDATE [group_table] AS G INNER JOIN [master_table] AS M
ON G.[ID] = M.[groupID]
SET G.[group] = '"& Group A & "'
WHERE M.[groupID] = '" & groupIDFromForm & "';"
Apply the ON from the join so that the foreign key and primary key are going to share the same value, and from there use the form to create a variable that you can use to identify the exact row. From there the program should execute the query correctly.

Microsoft Access - Creating a form which looks up data between 2 dates

For my College assignment, I have to create a database in Access, I have done 99% of my database, apart from this section which I'm stuck on.
In my DB, I have a tickets table, which contains records on order information and a field containing a date. For my assignment, I have to create a Form which reads from a Query.
For example, in my Form i have already created i have 2 Combo boxes with the dates already pulled from the Query. I need to be able to drop down one of the boxes and input 1 date, and then drop down the other box and select a different date, press a button and it generate me a Report.
The part I am asking for help on is the expression which is used to look up the data inside the Query. I tried using this expression, which Access said was too complicated.
[Forms]![frmOrdersBetweenTwoDates]![Combo33] And [Forms]![frmOrdersBetweenTwoDates]![Combo36]
My full SQL query is:
SELECT tblTickets.CustomerID, tblCustomers.FullName, tblCustomers.AddressLine1, tblTickets.OrderNumber, tblTickets.OrderDate
FROM tblCustomers INNER JOIN tblTickets ON tblCustomers.[CustomerID] = tblTickets.[CustomerID]
WHERE ((("WHERE [OrderDate]") Between [Forms]![frmOrdersBetweenTwoDates]![Combo52] And [Forms]![frmOrdersBetweenTwoDates]![Combo54]));
My expression/query now returns the report, but there is no data inside the report. How could i fix this?
Cheers.
Should post the complete query statement. Expect the filter clause should be like:
WHERE [date fieldname] BETWEEN [Forms]![frmOrdersBetweenTwoDates]![Combo33] AND [Forms]![frmOrdersBetweenTwoDates]![Combo36]
However, I don't use dynamic parameterized queries. I prefer to use the WHERE argument of OpenReport (same for OpenForm), in VBA:
DoCmd.OpenReport "report name", , , "[date fieldname] BETWEEN #" & Me.Combo33 & "# AND #" & Me.Combo36 & "#"

ValueList from ExecuteSQL() based query in FMP 12

I'm looking into upgrading our FMP11 developed solution to FMP12. For us, key functionality exists around the ValueList feature to DISPLAY one value (e.g. a description) while RETURNING another value (e.g. a UID), into the selected field.
I would be interested if you have been able to replicate this feature from the ExecuteSQL() function (I can successfully return a single ValueList ... having trouble with the above)
many thanks in advance
Giles
Based on the core functionality of value lists, you can't use the ExecuteSQL() function to calculate the value directly inside of the value list dialog box.
What you would have to do is create a table with a single record and two fields. Then you would use an ExecuteSQL() calculation to populate the first and second fields with data. It would be important to make sure you sort your data inside executeSQL() in the same order in both fields.
So your filemaker calculations would be (assuming the first field is key and the second is name and it's from a table called items, and you are looking for where key > 100)
keylist =
ExecuteSQL (
"SELECT key
FROM items
WHERE key > 100
ORDER BY key ASC"
; "" ; "" )
namelist =
ExecuteSQL (
"SELECT name
FROM items
WHERE key > 100
ORDER BY key ASC"
; "" ; "" )
You would then create a value list that uses keylist as the first field, and namelist as the second field, only displaying values from the second field.
It would be nice to have the functionality to calculate a value list, but as far as I know filemaker always needs to pull values from a source outside of the value list dialog box.

Create a new FileMaker layout showing unique records based on one field and a count for each

I have a table like this:
Application,Program,UsedObject
It can have data like this:
A,P1,ZZ
A,P1,BB
A,P2,CC
B,F1,KK
I'd like to create a layout to show:
Application,# of Programs
A,2
B,1
The point is to count the distinct programs.
For the life of me I can't make this work in FileMaker. I've created a summary field to count programs resetting after each group, but because it doesn't eliminate the duplicate programs I get:
A,3
B,1
Any help much appreciated.
Create a a summary field as:
cntApplicaiton = Count of Application
Do this by going into define fields, create a field called cntApplication, type summary. In the options dialogue make the summary field a count on application
Now create a new layout with a subsummary part and nobody. The subsummary should be sorted on Application. Put the Application and cntApplication fields in subsummary. If you enter browse mode and sort by Application you ought to get the data you want.
You can also create a calc field with the formula
GetSummary(cntApplication; Application)
This will allow you to use the total number of Applications with in a record
Since I also generate the data in this form, the solution I've adopted is to fill two tables in FileMaker. One provides the summary view, the other the detailed view.
I think that your problem is down to dupliate records and an inadequate key.
Create a text field called "App_Prog". In the options box set it to an auto-enter calc, unchecking the 'Do not replace...' option, and use the following calc:
Application & "_" & Program
Now create a self join to the table using App_Prog as the field on both sides, and call this 'MatchingApps'.
Now, create (if you don't alread have one) a unique serial number field, 'Counter' say, and make sure that you enter a value in each record. (Find all, click in the field, and use serial number option in'Replace Field Contents...')
Now add a new calc field - Is_Duplicate with the following calc...
If (Counter = MatchingApps::Counter; "Master Record" ; "Duplicate")
Finally, find all, click in the 'Application field, and use 'Replace Field Contents...' with a calculation to force the auto-enter calc for 'App_Prog' to come up with a value.
Where does this get you? You should now have a set of records that are marker either "Master Record" or "Duplicate". Do a find on "Master Record", and then you can perform your summary (by Application) to do a count of distinct application-program pairs.
If you have access to custom functions (you need FileMaker Pro Advanced), I'd do it like this:
Add the RemoveDuplicates function as found here (this is a recursive function that takes a list of strings and returns a list of unique values).
In the relationships graph, add another occurrence of your table and add an Application = Application relationship.
Create a calculated field in the table with the calculation looking something like this:
ValueCount(RemoveDuplicates(List(TABLE2::Program)))
You'll find that each record will contain the number of distinct programs for the given application. Showing a summary for each application should be relatively trivial from here.
I think the best way to do this is to create a separate applications table. So as you've given the data, it would have two records, one for A and one for B.
So, with the addition of an Applications table and your existing table, which I'll call Objects, create a relationship from Applications to Objects (with a table occurrence called ObjectsParent) based on the ApplicationName as the match field. Create a self join relationship between Objects and itself with both Application and Program as the match fields. I'll call one of the "table occurrences" ObjectsParent and the other ObjectsChildren. Make sure that there's a primary key field in Objects that is set to auto-enter a serial number or some other method to ensure uniqueness. I'll call this ID.
So your relationship graph has three table occurrences:
Applications::Applicaiton = ObjectsParent::Application
ObjectsParent::Application = ObjectsChildren::Application, ObjectsParent::Program = ObjectsChildren::Program
Now create a calculation field in Objects, and calculating from the context of ObjectsParent, give it the following formula:
AppCount = Count( ObjectsChildren::ID )
Create a calculation field in Applications and calculating from the context of the table occurrence you used to relate it to ObjectsParent with the following formula:
AppCount = ObjectsParent::AppCount
The count field in Objects will have the same value for every object with the same application, so it doesn't matter which one you get this data from.
If you now view the data in Applications in list view, you can place the Applications::Application and Applications::AppCount fields on the layout and you should get what you've requested.