Showing posts with label Tips&Tricks. Show all posts
Showing posts with label Tips&Tricks. Show all posts

Thursday, July 15, 2021

Android Screen Overlay Switching Greyed Out

Screen Overlay is one facility on Android to have some app hovering over all apps so that user can quickly access the app anytime.

One thing Google never tell you is that once an app is run with Screen Overlay, You cannot turn on Screen Overlay mode. To turn on or off you need to go to to Settings then click on the wheel on top left of the screen then choose "Draw over other apps" after that slide on "Permit drawing over other apps". The selection is greyed out.

The only way to enable the "Permit drawing over other apps" setting is to completely close the app that does Screen Overlay then make the changes before enabling the Screen Overlay app again.





Sunday, March 21, 2021

Javascript Listening for a specific Key press

 If you want to know what key was press in a web page, you will normally do a document.addEventListener('keydown',myFunc) function. However, if you only want to act upon s specific key then the situation is slightly different becauses addEventListener does not have function to return anything.

Fortunately, there is a "bind" function in the event listener. by defining the event listener as

document.addEventListener('keydown',myFunc.bind(event))

In myFunc then you could use event.keyCode to determine which key was pressed and bypass any other.

There is an issue here. You can't capture key combinations. Keys like Alt-s will be passed as two event instead of one thus the function is triggered twice. But for just a simple key press like pressing the space-bar, the script works quite well.





Monday, December 07, 2020

Internet Download Speed is Crawling

 Quite some time ago my win10 browser loading suddenly become sluggish. I check with Ookla Speed Test shows that the download speed is just 6 mbps whereas I subscribed to 1 Gbps. The upload speed is very much faster but still well below the 1 G bit as subscribed.

Tried various methods of finding out why the download is slow but to no avail. Checking the speed on my handphone proved that the router is OK thus not service provider problem. It is only the laptop that has the problem. It really puzzles me as it is not due to browser issue since Ookla has a app that could perform the test without using browser.

After a month or so of intermittent attempts to find the fault, I finally found a clue. Netizens mentioned that SmartByte Network Services could slow down network.

I uninstalled SmartByte and the speed went up to almost 1 Gbps. SmartByte come pre-installed with Dell laptops. There are instructions in the internet that teaches you how to uninstall it. One such example is https://windowsreport.com/smartbyte-services/.




Tuesday, October 27, 2020

digiKam Used for Managing Flora and Fauna Photos

 I need to use an application that could manage those photos of flora and fauna so that I could easily refer to them or search for specific specie. After the demise of Picasa, I found an application called digiKam that could perform most of the functionalities like Picasa. 

digiKam has lots of functionalities that are available. Here I will only talk about those I would use to manage flora and fauna photos.

Showing photos that are stored in directories grouped by directories is the basic requirement. It won't work if I have to go to individual directory to show the photos inside. digiKam did a good job by showing an entire directory with subdirectory as a selectable list.

In addition to directory aka Album, digiKam is able to show lists by Maps, Tags and Dates. It also have a search by title. Other list types are available but is of little use to me. Tags list is mentioned together with Tag editing below.

Maps listing is an interesting feature. You can show a list of photos that is defined by a square selection or select a group of photos that is grouped by digiKam. I find it extra useful to identify flora pictures. It all goes by memory. If you have seen the flora before and remembers a rough location, you could list the photos in the area and try to find the flora. For fauna, it is a bit difficult as they don't stay in the same place unless they are territorial.

I also contributes to iNaturalist. The location can match with digiKam map to show a list of photos in the same area. It helps if I have already identify the flora and have a picture of it. Inversely, I could use my photo's location and find in iNaturalist to see if there are any observation of the same kind. iNaturalist have the same map area list like digiKam.

GPS, Tags and Title are the most important information that is stored in a picture. digiKam allows the editing of these tags as individuals and group editing. 

Tags are usually done as a list. digiKam stored hierarchical tags in its database. It did not store the data in the pictures because other applications only look at tags as a list. This feature is best suited for me as I normally set the taxon family and Gender as separate tags. digiKam is able to use tags to show the list of photos that has the same tag. Now I could use the hierarchical listing to see the gender in a family instead of seeing the whole list of photos in the same family. 

Tag editing also benefits from the hierarchical arrangement. When adding tags I had to find the family and gender separately before adding them. Now I just need to find the gender and the family will also show up if it already exists. This save me from having to find the family name for the gender.  A time saving feature.

Zooming is a very useful tool. digiKam allow list photo to be zoomed to a size comfortable. I zoomed to a level that shows 5 photos in a row. That is most comfortable to see enough details of the photo. 

By double clicking a photo you could see a zoomable view of the photo. It even have a full screen zoomable view of the photo. You could set it to full screen when you double click. This is very useful to see clear details of the photo so that I could find the specific character of the flora and fauna.

Rotation. Sometimes the camera does not automatically store the rotation thus digiKam showed the photo in the wrong position. digiKam has a rotation setting so that you could view it properly. However, I am not sure if the information is stored in the picture after that. 

Photo editing. Not the usual kind of editing feature is available. It is just a set of enhancement that allows photos to be adjusted. I usually use auto color to adjust the photo. Other adjustment features may be useful but is of less interest to me.

Grouping in a list. It is a unique feature but it does help if you go for a tour and need to group the photos by the day. You could group the photos in anyway. I find it useful to avoid seeing those photos that are not related to flora and fauna.

Panorama is not part of the feature required for flora fauna management. But it is useful for people who does not have a panorama camera to stitch few photos together to make a panorama view/ However panorama is not a digiKam application. It has to be installed from outside. Luckily when you select panorama in digiKam, it allows you to download hugin (pto2mk) and GnuWin (make) from internet. Download and install, the panorama feature will be activated.

In conclusion, it is useful to me to manage my photos in the flora and fauna sense. This application is available for Windows, Mac and Linux.






Saturday, June 15, 2019

Exercising by Heart Beat

Normally one would want to exercise with some repeatable routine. Some go for fixed time. Others go for distance. More health conscious people will want to stick to an exercise/training routine depends on the type of exercise done.

I usually go for speed based exercise as I do walking and cycling. Recently, I am obsessed with heart beat based exercise. It is not scientifically proven but based on the ample talks about lowering heart beat, a controlled heart beat during exercise moves one towards lowering it. It will be good for controlling hyper tension, high blood pressure.

Before launching on the methods used to keep heart beat within a range during exercise, it will be good to about the basis of heart beat measure. According to scientific figures, the maximum heart beat a human can have is 220 beats per minute (BPM). Individual person's maximum heart beat is 220 - number of years of your age. People who exercise constantly will have their maximum heart beat considerably higher than normal people's heart beat.

Minimum heart beat depends on individual. Some athletes have resting heart beat around 40 BPM. Most people's heart beat is between 60 - 100 BPM. Children aged 6 -15 is around 70 - 100 BPM.

My range of heart beat I want to control while walking is 99 - 108. It is at the lower end of medium exercise range. The reason is to avoid excessive sweating. It is not easy to control the heart beat at this range as any lower than 98 BPM means I am out of medium exercise range. This is especially true if I don't do warm up before walking. It tends to fluctuate very much till the body is warm up.

Monitoring heart beat while cycling is a bit dangerous. However, all vehicle drivers including motor-cyclist have to keep monitoring their speed while driving. Their speed is very much higher. Just ensure that the coast is clear before you take a peek at the heart beat monitor. I only do it while cycling on long stretch of PCN or cycling path.

Depending on the type of cycling done, the heart beat range can be different. Usually, if I want to go for speed, I abandoned heart beat monitoring. Just go fast till your limit. On the other hand, for standard exercising, I go for 155 plus minus 10. It is at a comfortable heart rate without stress. Coincidentally, 155 is my maximum heart beat (theoretically).  Individuals must try and error to find a comfortable cycling speed for themselves.

At 155 BPM the speed of travel is basically below the 25 KPH limit of PCN. It is therefore safe and within the regulation.

GARMIN Connect has a stress measurement statistic page. It is to show how often you get stressed. My stress region is generally non existing except at the beginning  and end of exercise. It could be a result of my method used but there is no proof and I don't bother to prove it.

Below is a typical walking speed and heart beat chart.






Friday, May 24, 2019

Windows 10 grinds to a halt

First it was an extra application called Chromium get installed. Unable to install thus use IObit uninstaller to remove the program.

After that the computer suddenly goes unresponsive. It takes over a minute to respond to clicks.  Task manager indicated that CPU usage is low and Disk activity is low. It just puzzles me.

Nothing I do could solve the problem. Manage to get Win 10 to boot to safe mode by forcing it to close then start again 3 times.

Even at safe mode, it also responses not that well. On searching from internet, it was suggested to check page faults. Starts Performance Monitor and adds page fault. The percentage is 100. Netizens suggest using Sysinternals, Process Explorer. Downloaded it and run. There is an item that has more than one million page fault. It is Mcafee.

Uninstalled it and the system works as normal. One problem still persists. Windows Defender antivirus shows that "the virus protection is managed by other manager". No facility to set it back. Well, that is not part of this issue.



Monday, March 25, 2019

Evaluation of Careeach HR

The Careeach HR is a free tracker provided by Health Promotion Board. The following is a comparison with Garmin Forerunner 935. The comparison is one way. That is to say only compare what Careeach HR has to Forerunner similar functionality only. It is unfair to compare with all the available features of Forerunner 935.

1. Steps - Steps are fundamental feature however it is noted that Careeach HR always track about 10% less compared to Garmin even the steps setting are the same. Garmin seems to show slightly more steps than usual.

2. Heart Rate - Careeach heart rate measurements are very unstable. It can go above 150 while Forerunner shows a modest sub 90. The measurement can simply drops well below 80 while exercising and can drop out of continuous measure mode unexpectedly. Its auto mode is most unreliable. I always turn on continuous mode while exercising. Garmin shows a bit less accurate in auto mode but function well in continuous mode. I can use Garmin to control the heart beat rate but not Careeach. The latter heart beat goes up and down too much and too quickly. Careeach calculates max heart rate according to age. It will buzz user to slow down if the heart rate goes beyond heavy range. Garmin does not buzz user and its range is fixed percentage.

3. Display of the Careeach tracker is always off but can be activated by hand or a twist of the hand but often have to make very large angle swing of arm in order to activate it. Garmin does not have this feature as its display is always on. Both tracker will switch over to clock mode if it not in continuous measure mode. Garmin heart rate display will switch to clock mode after a while but it will stay if it is displayed in sports tracking mode.

4. Upload of data is a hassle. At times the HPB App has to be turned off and on a few times to make it update. Sometimes, the whole hand phone has to be rebooted to get it to work. Garmin update to HPB is via its apps. Although two steps are required but the updates are usually reliable.

5. Charging of Careeach is via USB but the display can some times go straight into full by just plugging in the tracker. The full charge display can stay till it run suddenly out of juice thus lost valuable data. Turning off and on the tracker does not help. Garmin charging can be a bit of problem due to contact issues but never have wrong display issue.

6. Careeach states that its tracker is splash proof. However, one tracker died after going though a light drizzle. Had to replace it. Garmin is water proof up to 50 meters.

7. Battery life of Careeach is way too low to be compared to Garmin. But it can last at least 10 hour of continuous heart beat tracking mode. It could last 2 days or more on normal mode.

8. Careeach will buzz user if they stay static for too long. I am not sure Garmin has it.

For a free device, Careeach HR could be used for tracking steps. Heart rate is at best good for indicator only. Just don't exercise in the rain or use quick charger to charge it.




Friday, January 11, 2019

SQL Aggregate Function as Table using PHP

SQL aggregates as defined by netizens is "perform a calculation on a set of values to return a single scalar value". We often use aggregate functions with GROUP BY, HAVING clause of SELECT statements.

While it is very simple showing tables with just one aggregate or a set of aggregate functions using SELECT and GROUP BY then showing the table as retrieved by the SELECT statement, the table is practically vertical listing in nature. For example

SELECT states, people, SUM(revenue) FROM sales GROUP BY states,people order by states DESC

will show when you format it as table from the query result directly.

People   Revenue   State
Sam       100,000    Selangor
Ken        200,000    Selangor
Joe         100,000    Johor

What if you want to show all the people in the state regardless whether there are sales made by individual and the percentage of their Revenue for the state? It is quite impossible to do it in a single select statement.

The following method shows how to use a single statement to get a list of people and their revenue plus percentage of the group.

First we create an associative array from a list of people and populate it in the array.

$keys=array('Sam','Ken','Joe','April');
$values=array('Revenue'=>0,'Percent'=>0);
$total=0; //totals of the group
$revenue=array_fill_keys($keys,$values)

Retrieve the data using the previous SELECT statement like below. The example uses SQLite.

$db=new SQLite3('revenue.db');
$result=$db->query("select people, sum(revenue) from sales group by people");
while ($row=$result->fetchArray(SQLITE3_NUM))){
$ppl=$row[0];
$revenue[$ppl]['Revenue']=$row[1];
$total +=$row[1];
}
$db->close();
//do calculation and populate table
foreach ($revenue as $key=>$row){
$percent=round($row['Revenue']/$total*100,2);
echo " {$key}
{$row['Revenue']}{$percent}";}

Obviously, the above could be done by 2 queries. One to retrieve the overall total and the other one as above. However, what if you want to list the sales by date and show the people in columns? That is not an easy task representing it in one or two SQL.

You could retrieve the query by revenue grouped by date and people. Your array setting will be

$keys=array('Date','Sam','Ken','Joe','April');
$people=array_fill_keys($keys,$values)
$revenue=Array(); //you could fill the array with every date in the period you choose.

In the while loop, do as follows (assuming date is unix datetime),

$rdate=$row[0]; // the date field
if (!isset($revenue['A'.$rdate])){
$revenue['A'.$rdate] =$people;
$revenue['A'.$rdate]['Date']=date('m/d/Y',$$rdate);
) // set up the array and populate the 'Date' of the array for easy retrieval later
$people = $row[1] //the people field
$revenue['A'.$rdate][$people]=$row[2]; // the revenue field

With this you could populate the whole columns of people with date as first column. Displaying the table is then a breeze using the FOREACH example above.



Saturday, December 29, 2018

SQLite syncing with remote data to act as local data

There is a need to get a set of data from a remote server and distribute to a group of local computers. The data must not be deleted then inserted. The data also may not be available on remote server due to it being closed and removed.

If the data cannot be deleted (truncated) then the only way is to do "insert or ignore" so that existing data is either updated if it exists or inserted if it is not. Meanwhile, there is a problem of remote data does not exist while local data exists.

Well, it is quite easy. Two tables are used. One for the main table with a key index field and the other one only the key index field. Both table index uses the same field.

When importing data, both tables are inserted with the remote data. The second table was truncated before the import starts. This means the main table contains new and old data while the second table only contains the new data. At the end of importing, just simply delete from the main table where the index field not exists in second table. Thus only the imported data remains in the main table.

Example of the "insert or ignore" goes like this

Insert or ignore on maintable (f1, f2,f3....) values ('x1', 'x2, 'x3'...);update maintable set f2='x2', f3='x3' where f1='x1'

It seems that the above will insert and then update if the index is not found but it is still better than using two sql statements to insert or update plus one statement to check whether the index exists before doing either insert or update statement.

Example of the delete command goes like this

delete from maintable where  f1 not in (select f1 from secondtable)

The main table can then be access by local users.



Monday, October 29, 2018

Printing Receipt Using PHP again

Last blog on this subject is at Printing Receipt. It talks about a single use printing where there is only one printer for one purpose. There are requirements to use same type of printer for different receipts. Like for example, one company wants to print queue numbers, receipts and barcode travellers using the same type of printer.

It would be easy to just create three PHP page to do the work. Here the attempt is to use a single PHP page like a driver that can print to different printer for different purpose. It becomes like a class file. Also the print codes stays with the app that does the printing so that you do not need to look for specific PHP page for the printing code.

The PHP code is like the previous blog with a slight change. The printer is a Brother QL720NW which does not work with fwrite_stream. A simple fputs will work fine.

All that is required is to send the printer IP and the print code to the page as parameter using POST. Now the twist is that POST only sends AlphaNumeric not the full ASCII. Escape codes usually includes ASCII less than 32. The trick is to convert the print code into Base64 first before sending. At the PHP, just use base64_decode to convert it back before printing. The code is as below

$ipAddress = $_POST["IP"];
$printCode = $_POST['PrintCode"];
$printCode = Base64_decode($printCode);
$fp = fsockopen($ipAddress, 9100);
fputs($fp, $printCode, strlen($printCode));
fclose($fp)

With this, you can send to different printer with a different print code using the same PHP page. The advantage is that any app that can do a POST will be able to do printing.

Most programming codes will have base64_encode (or similar). If not then there are probably programmers who wrote a code library in the same programming language. If it does not have then you may have to create the code yourself. The trick is to convert the byte into Binary then take every 6 bit and convert it back to number to match against a table see https://en.wikipedia.org/wiki/Base64. to get the ASCII character. It is not that difficult.




Wednesday, November 01, 2017

Filemaker add new records into related tables/portals

Filemaker has this nice feature of being able to add new records to a related table without having to go to the table and insert new record.

What you need is simply click on the relation link and click "allow creation of records" in the related table side.

To add a new record just change the value in any of the fields in the relation table.

There are times when your relation is one to many and you need to create the records in similar ways as above. Well, it is possible but you have to do a few setups.

First you must have the relation setup as mentioned before. Next you need to create a portal in the form view of the original.

If you just want to insert relation rows manually, just go to the portal and click on the last blank row and type in the new data.

To insert the new records in scripts is a bit more complicated. You need to do further setup. The first thing is you must set the portal to allow "vertical scroll". Also, you must name the portal. In your script, you need to do two things.

Go to Object; []
Go to Portal Row:[last]

After that you could just use "Set Field" to insert any value.

The setup looks simple but if you missed the "Go to Object" script, it will never work.



Sunday, October 29, 2017

Filemaker Finding a Range of Dates

Finding a range of dates in Filemaker is not new. It is available in Filemaker Helps but since it is quite unusual, it is worth repeating.

To find a date range, you need to enter Find mode. At the date field enter the date range like .. then press enter. Note that the date entered is the system date format not the displayed date format as the display date format may not be the same as system date format.

To do a date range find in Script is slightly more complicated. You need to create two date type global fields.  These global fields is for user to enter the search date range.

First enter a script step to start find without definding the find requests. Set the pause off. Then set variable to the field with the two global fields as start and end date like below

Enter Find Mode []
Insert Calculated Result [Select; mytable::mydatefield; mytable::GlobalStartDate &"..." & mytable::GlobalEndDate]
Perform Find

There are instances where your date range is not taken from user's input. In that case you have to modify the script a bit.  Get rid of the 2 global fields and create two variables that contains date values. Here I use static date values. You can use variables to define the date values.

Set Variable [$startDate; Date( 8; 1; 2017)]
Set Variable [$endDate; Date( 8; 31; 2017)]
Enter Find Mode []
Insert Calculated Result [Select; mytable::mydatefield; $startDate &"..." & $endDate]
Perform Find

Normally the date range is by month. It is easy to modify the above script to search by month. 

Set Variable [$startDate; Date( 8; 1; 2017)]
Set Variable [$endDate; Date( 8+1; 0; 2017)]
Enter Find Mode []
Insert Calculated Result [Select; mytable::mydatefield; $startDate &"..." & $endDate]
Perform Find






Sunday, October 01, 2017

Scheduling of Employees using Filemaker

There was a request to write an app using FileMaker to do employee scheduling as part of a overall project for HR to check employee attendance. The request is quite peculiar.

1. The business opens 7 days a week.
2. Each employee is entitled to have 2 days OFF each week.
3. Supervisor and back up must not be off on the same day.
4. Special task and back up must not be off on the same day.
5. Other team members must be evenly distributed across the week.
6. The whole team must be randomly and evenly distributed across the week.
7. The order of schedule by person must also be random.
8. Employees can request for OFF on specific day on per request basis (to coincide with their Leave).
9. The schedule must be displayed by month with days of the month on columns and employees on rows.

Although you can define up to 250 million fields, it is impossible to use date for fields/columns otherwise you must keep adding fields with specific date. FileMaker does not have scripts that could create fields and add to table layout. It is easier to use employee for columns as the number of employees are limited. Moreover, the business is small thus easier to set a maximum number of fields/columns and increase them when necessary.

The first table is structured with first field/column as date followed by a fixed number of employees with field names designated as Exx. xx denotes a two digit leading 0 number. Its a small business thus need not set a large number. The first row is designated as Employee name. The date field is blank and each employee column is set with an employee name. It is easy then to just add rows with dates by month. This is highly unconventional. However, since the requirement is to show by month, it is still viable.

The search function should have 2 criteria

1. blank date
2. dates of the specific year/month.

Sort the records by date and you get a nice table with employee on row one and the rest of the dates below it.

Item 9 is using dates as columns. Since it is displayed by Month, It is easy to create a temporary table by transposing the rows into columns and add weekdays as row 2. The table have 32 fields. First field is employee name. Next field is day 1 of the month and so forth.

It is easy to create one row with days of the month as data. Row 2 will then be the dayofweek translated into text using case function. I am sure you know how to translate number to text.

The method is to use ExecuteSQL to retrieve one employee at a time for the whole month. Since we set a maximum number of employees. We can retrieve the whole list of employee like below.

ExecuteSQL("select E01,E02 from firsttable where scheduleDate is null fetch first 1 row only";¶;"")

We will also retrieve the whole months of data like below

ExecuteSQL("select E01,E02 from firsttable where sMonth=? and sYear=?";¶;"";firsttable::gMonth;firsttable::gYear)

gMonth and gYear are global fields for user to indicate which month and year to get data from. sMonth and sYear is the month and year of the date (calculated field)

Do a loop within loop. The outer loop adds a new row and uses the result of the employee list to retrieve them one by one. The inner loop picks up one particular value from the list as defined by the first loop.

For example, outer loop choose item 1, inner loop goes through the entire list but picks item 1 from list only. This will populate the table row by employee E01 and those E01 values by date.

The result is a nice transformation of row into columns.

The next thing is to fill in the data for the first table. Use a drop down list tor each field in the table. It ensure standardized data definition.  This will allow leave applications and OFFs to be added into the table. With this data added, we need to do the actual scheduling.

Item 8 above allows for pre-request OFF days. Therefore, the scheduling must take into consideration the pre-defined off days. It is much harder to find those pre-defined off days and leaves and do a schedule on the first table directly.

Therefore, a third temporary table is required. The table structure is similar to the second table except the columns are only 7 which consists of the days of week starting from Sunday. We retrieve the weeks data from the first table sorted by date like the translation method for second method except we don't have to add the first 2 rows. Also, you should skip those columns without employee name defined to shorten the computing time.

In addition to retrieve employee name and the 7 days. we need to define additional fields to facilitate the scheduling. This is for reasons which we will explain later. The additions are as follows

1. We need to find out which Employee is assigned to which field/column in the first table. This is to allow for locating the particular employee after we do random sorting.

2. We need a column to fill in the random number for sorting purposes.

3. We need 7 column as summary fields (count) for each day of week to check the off and leave distribution.

4. We need a global field to store the first day's date so that we could update the table later.

Now, we retrieve the data from the first table and transpose it in to this third table. However, there is a twist. Instead of retrieving the literal text, we have to translate it to 1 or 2. Leaves are designated as 1 and off and pre-defined OFFs are designated as 2.

Immediately you will see that the 7 summary fields will show the count of all leaves and offs for the day.

Item 3 requires Supervisor and backup to be scheduled not on the same day. Obviously, there must be at least 4 days available for scheduling. First schedule one person by randomly choose between the two. Just get the list of days which are blanks. You can just go to the row and read each day to see if it is blank then add the field name to list. Randomize the list and set the first two day as OFF. you must first count the number of 2s. Set the number of OFFs accordingly.

The schedule for the second person is a bit tricky. You must use a count function in the SQL and limit to the two person to retrieve the blank dates. This will effectively ensure that only those days that both are not schedule can be selected. Randomize the list again and set the first two days as OFF. Before setting any OFFs, you must first count the number of 2s. Set the number of OFFs accordingly.

Repeat this for Item 4. Suggest to put Supervisor and back up as row E01 and E02. Special task and backup as E03 and E04. This will make it easy to identify which one to schedule.

Now, before we could do anything for the rest of employee, we need to randomize the employee list. This is easily done by filling in a random number. Random numbers in FileMaker are from 0 to 1. There are custom functions that could provide integer random numbers within a range. Suggest to use a range at least 3 times the maximum number of employee list in table 1.

Sort the table by the random number field. This will effectively randomize the employee list. Note that it is the entire employee list. This include supervisors and special tasks. This action satisfy Item 5 and 6.

This is when the 7 summary fields are coming into play. We will choose the first summary field that has the smallest count. Since is it is summary field, it appears in every row. First set a variable with a large number. Second set a variable that is blank. Go through each summary field. if the count is smaller than the first variable, replace the first variable with the count and set the second field as the corresponding field name of the day of week. Just set the fiend name as OFF ("2").

Go through the entire employee list using a loop of 2. You need to redo the random number and sort again to scramble the employee list before the second loop. To schedule exactly two OFFs, you need to first count the number of 2s for the person. If it is already 2 then skip to the next employee. This will effectively allows for pre-defined OFFs to be treated like off. You can even repeat the same week 's schedule and it will not alter the schedule if there are already 2 OFFs assigned to the person. This will satisfy Item 7.

Once the schedule is complete, you need to translate the table back to the first table. First limit the first table to just the week and sort it by date. Remember we stored the first day of the week as date? Just create 7 variables to store a date by adding 0 to 6 days to the first date. Use the 7 variables to create 7 search condition and put them in a "find" function.  Use a SQL to read the third table by the weekday and the employee field name.

Again we need to do a loop on the rows in the first table. Get the date and translate it to dayofweek text. We do a inner loop to go to the whole list of the third table to find the employee field name and the particular day of week. Update the first table with "Off Days" if the first table is blank and the third table data is "2".

The result is a nicely updated OFF schedule.

Note that you may need to get the data of the field by using GetField("fieldname"). This is to allow for getting the content of the field by calculated field name.

You also need to do update to fields by using "Set field by name("fieldname"). However, the field name must be in this format "tablename::fieldname". I don't know why two different ways of defining field names but that is FileMaker. I end up using Get(LayoutTableName) & "::" & "fieldname".






Thursday, March 30, 2017

Filemaker hiding field object in Table View

There are times when we don't want to see some fields based on the values of another. In form view you can easily set it to "hide when" and set the condition to hide it.

However, in table view, the field is not hidden (up to V15). What are other means to hide the field?

I used a simple "conditional formatting" setting and set the text color to the background color. It is still shown at least not distinguishable to user.

It is a work around for Filemaker Table view which is unable to hide the object despite the "hide when" setting is set.