Two consecutive days I saw kindness.sg promoting "kindness". The Singapore Kindness Movement was formed in 1997. Its aim is "to encourage Singaporeans to make a positive commitment to gracious living through simple acts of kindness."
The aim is nothing but perfect. So it seems. Look at the whole page ads below.
What has it to do with kindness? The picture practically say that you are not kind to snap a photo of people misbehaving. Insteads you should confront the person. The real kindness is to show a photo of people giving up their seats to the needy.
This photo portrays the same message. You should not take photo. Instead you should confront the angry man. A show of empathy to who? The waitress or the angry man? The wordings in the photo says you can "stand by", "watch", "take a video" or "step in and try". Which action shows empathy? The last one? It is practically asking people to confront the angry man. Should this photo be showing empathy towards the server and not to scold her?
It keeps saying "Kindness" yet it points to bystanders and say that they should act. By acting it is equal to "kindness"? I don't know what's wrong with the mind of the organization. It is advocating everyone to act in confronting wrong doers as if bystanders are experts in that area while it by itself says nothing about themselves telling the wrong doers that they should be gracious and do what is right.
The two photos actually show the adverse message. It is saying you should not take photos/videos neither should you do nothing. Is it wrong to do what they try to dissuade? Are we a confrontational society? If it is not handled properly it may well hurt the peace maker's feeling or make the situation worse. Is it not better to educate the wrong doers rather than the bystanders?
Taking a photo and post online is a bad thing? It is not graceful? Many people do not want to directly confront others. They try to vent their dislike by posting such bad activity online. The action by itself is not really a correct thing to do but it could be the only way many people try to show their dislike.
By posting online, the public will be aware of such event and thus avoid being the center of attention. This is far better than trying to talk to individuals to solve the issue. Would you want to do bad things in public knowing that your bad act may be shown to the whole world? I do agree that it damages the wrong doers image. A graceful/kind person should not have done that in public in the first place.
Most public figures faced the same issue. They have to ensure that they do not do wrong in public otherwise the whole world will knows about it. Why then should individuals be exempted. You did it in public and people capture/record and show it in public. There is nothing wrong to that. The only thing I strongly disagree is to have paparazzi style of stalking people to capture their embarrassing moments. That is totally evil.
EU has passed a law to have "rights to be forgotten". That is a good thing. At least it gives people who did wrong in ignorance/rage to be given a chance to be forgotten. That is what I called "graceful society". Maybe kindness.sg should advocate this act to be passed by parliament instead.
Wednesday, April 27, 2016
Saturday, April 23, 2016
Pain in the Ass
Decades ago while I was studying in Baptist Seminary, a Professor said that I have a gift of teaching. I did not have tertiary education neither did I complete the Seminary course. So am I still qualified to be a teacher? Most Christians will says that it does not matter whether I got a paper qualification. But I have a strong feeling that the "teaching" may be a non academic one.
As life goes along, I slowly realized that I have a knack of finding fault with everything. Take the example of my former church. The group was led by a missionary pastor. They need to have a place to worship so they joined one of the member's church. Since it is a Chinese speaking community. The English speaking group have no problem remaining a closed group. As time goes, the group did not really become big enough to expand out but the missionary pastor wanted to "plant" a church and move on so he encourages the group to split from the mother church to become an independent church. Obviously, the whole group thinks it is alright except myself. Ultimately, they moved on. My name was removed from the mother church registry but I did not actually join the new church thus becomes a wondering Christian.
I joined a group but find the organization lacking in its activity. They seems to treat the activity as a duty so only builds close relationship with the pioneers. New comers were left with having to join them or fend for themselves. I pointed out some oraganization event issues in my post a few times and was brushed off.
In FB, I used to point out that some of the posts were inappropriate. At times I even have a long "conversation" with individual. Most of them just suggest that I take it as is. however, I don't think that a wrong should be accepted. The most prominent "conversation" is about PCN. There are so many discrepancies yet there are people who just tell others to shut up and live with it.
In the internet there are so many posts that did injustice. Take for example. there was a comment that "a woman should wake up a sleeping man sitting on a priority seat so that he could give up the seat for a pregnant lady instead of posting a picture shaming him". There are a few things that weren't right.
1. The author did not take into consideration that the lady may not be the assertive/confrontational type.
2. He also did not take into account that by taking the picture of the lady taking the picture, He also failed to do what he said she should do.
3. By saying that Singapore is a "Civilized country" bring us to laughter. If it is true then there will not be opportunity of people taking pictures to shame individuals. There is even a dedicated site "Stomp" to show them.
4. He should rally the community to be more caring rather than shaming her trying to get things right.
5. What he did is to shut the mouth of those who point out wrong. It is like asking the prople to close their eyes and say that the world is beautiful.
News about a woman who sexually abused an underaged were not charged with the appropriate law. It is understood that the law should be impartial to both male and female offenders. However, if the law somehow become partial due to the language it uses, then it cannot be applied to another sex. Some netizen insists that the judge is wrong. These people judge the judge on moral issues. However, the judge must not be influenced by citizen's moral value otherwise how could the judge be impartial. It is up to the judicial department to work it out.
Advertisements are every where. Do you notice that some advertisements are not correct?
I have started a FB page "Windows into Life". It is a page where I voice out things that are not correct. I do include things that are nice and good to make it a more balanced page. Obviously, it will be "stomping" people.
I don't really care what people think about myself. If they don't like me let it be so. I am a loaner. I do not need people to support me so that I can feel good. I my end up dying alone. Well, I rather be at peace with God than at peace with men.
Well, do I insist that I am right and harassed people to change? No. That is not what I am aiming for. I did not insist that they amend their ways. My duty is to point out not to guide.
My motto is "If you insists that you are right, you stopped reasoning". If some one is able to point out that I am wrong and have the correct reason, I will apologize and retract my words. In this world there is no absolute right or wrong. In that case I am merely stating my point. It is up to you to accept or reject.
Some may say that I am judgemental. No. I do not judge. Only God judges (Matt 7:1-3). I point out the facts and state it. You judge for yourselves. There is nothing personal against the person or things.
Some may say that I am judgemental. No. I do not judge. Only God judges (Matt 7:1-3). I point out the facts and state it. You judge for yourselves. There is nothing personal against the person or things.
Nobody likes to be told that they are wrong. That includes myself. So a person who goes everywhere and start correcting people, that person is really a pain in the ass. That's me. I point out because I care. Would you?
Thursday, April 21, 2016
Web Based JS Charts again.
Constricting web based charts is quite a simple job. Using SQL statement to pull a summary of the data, structure it according to the requirements of the JS Chart and there is the charts. On the previous post, I have mentioned the use of Rgraph (http://jnhiew.blogspot.sg/2016/04/javascript-charts.html) to achieve the purpose. This post is to show how it could be done.
First lets start with constructing the data. The format of the data is [0,1,2,3,4,5,6].
The SQL to get the data will be
SELECT SUM([yourvaluecolumn]) AS mysum,[yourfield] FROM mytable WHERE [yourcondition] GROUP BY [yourfield] ORDER BY [yourfield]
The PHP code to extract sqlite data is as follows
$db= new SQLITEDatabase('sqlitedb');
$query = $db->query('[your query statement]');
The result will be an array something like below
123, 'abc'
456, 'def'
789, 'ghi'
1012, 'klm'
To extract the array, use the following
$csv = "[";
$csvkey="[";
while ($data = $query->fetchArray(SQLITE_NUM){
$csv.=$data[0].",";
$csvkey .= "'". $data[1]."',";
}
$csv = rtrim($csv,",")."]";
$csvkey = rtrim($csvkey,",")."]";
The RTRIM command is to remove the last comma.
In the javascript replace the "data:" and the "labels;" line with
data:<?php echo $csv; >,
labels::<?php echo $csvkey; >,
The above is only for simple charts with one set of data. If the data is required for multiple bar or multiple line chart like showing the set of data in groups by month, then the format is different for "data". The "labels" will remain the same. The format of the data is like
[[1,2,3],[4,5,6],[7,8,9]]
Before you do anything, you must extract the labels from the database. The reason is that there will not be a data result if the field value does not exist for a particular month causing the number of columns become variable. Furthermore, it is impossible to predict the labels without first extracting it before hand. Therefore, the first thing to do is to extract a label list and an 0 initiated associative array that includes all the labels.
$csvkey="[";
$csvary=array();
$qlabel = $db->query('SELECT DISTINCT [yourfield] from mytable order by [yourfield]');
while ($data = $qlabel->fetchArray(SQLITE_NUM){
$csvkey.="'".$qlabel[0]."',";
$csvary[$data[0]]=>0;
}
$csvkey = rtrim($csvkey,",")."]";
The SQL will be
SELECT SUM([yourvaluecolumn]) AS mysum,[yourmonth],[yourfield] FROM mytable WHERE [yourcondition] GROUP BY [yourmonth],[yourfield] ORDER BY [yourmonth],[yourfield]
The format of the result will be
123, 'March', 'abc'
PHP code will be as follow
$dta=array();
while ($data = $query->fetch(SQLITE_NUM){
if (!isset($dta[$data[$data[1]])){
$dta[$data[1]=$csvary;
}
$dta[$data[1]][$data[2]]=$data[0];
}
$data2="[";
$key2="";
foreach ($dta as $key=>$value){
$data2.="[";
$key2.="'".$key."',";
foreach($value as $k2=>$v2){
$data2.=$v2.",";
}
$data2=rtrim($data2,",");
$data2.="],";
}
$data2=rtrim($data2,",")."]";
$key2=rtrim($key2.",");
Replace the two JS as before.
data::<?php echo $data2; >,
labels::<?php echo $key2; >,
Add an extra option to the option in JS. It will be shown as legends.
key::<?php echo $csvkey; >,
Obviously, there are times when there is a need to do multiple stacked bar group by month. I will leave it to you to figure out. Hint:- Third level array.
First lets start with constructing the data. The format of the data is [0,1,2,3,4,5,6].
The SQL to get the data will be
SELECT SUM([yourvaluecolumn]) AS mysum,[yourfield] FROM mytable WHERE [yourcondition] GROUP BY [yourfield] ORDER BY [yourfield]
The PHP code to extract sqlite data is as follows
$db= new SQLITEDatabase('sqlitedb');
$query = $db->query('[your query statement]');
The result will be an array something like below
123, 'abc'
456, 'def'
789, 'ghi'
1012, 'klm'
To extract the array, use the following
$csv = "[";
$csvkey="[";
while ($data = $query->fetchArray(SQLITE_NUM){
$csv.=$data[0].",";
$csvkey .= "'". $data[1]."',";
}
$csv = rtrim($csv,",")."]";
$csvkey = rtrim($csvkey,",")."]";
In the javascript replace the "data:" and the "labels;" line with
data:<?php echo $csv; >,
labels::<?php echo $csvkey; >,
The above is only for simple charts with one set of data. If the data is required for multiple bar or multiple line chart like showing the set of data in groups by month, then the format is different for "data". The "labels" will remain the same. The format of the data is like
[[1,2,3],[4,5,6],[7,8,9]]
Before you do anything, you must extract the labels from the database. The reason is that there will not be a data result if the field value does not exist for a particular month causing the number of columns become variable. Furthermore, it is impossible to predict the labels without first extracting it before hand. Therefore, the first thing to do is to extract a label list and an 0 initiated associative array that includes all the labels.
$csvkey="[";
$csvary=array();
$qlabel = $db->query('SELECT DISTINCT [yourfield] from mytable order by [yourfield]');
while ($data = $qlabel->fetchArray(SQLITE_NUM){
$csvkey.="'".$qlabel[0]."',";
$csvary[$data[0]]=>0;
}
$csvkey = rtrim($csvkey,",")."]";
The SQL will be
SELECT SUM([yourvaluecolumn]) AS mysum,[yourmonth],[yourfield] FROM mytable WHERE [yourcondition] GROUP BY [yourmonth],[yourfield] ORDER BY [yourmonth],[yourfield]
The format of the result will be
123, 'March', 'abc'
PHP code will be as follow
$dta=array();
while ($data = $query->fetch(SQLITE_NUM){
if (!isset($dta[$data[$data[1]])){
$dta[$data[1]=$csvary;
}
$dta[$data[1]][$data[2]]=$data[0];
}
$data2="[";
$key2="";
foreach ($dta as $key=>$value){
$data2.="[";
$key2.="'".$key."',";
foreach($value as $k2=>$v2){
$data2.=$v2.",";
}
$data2=rtrim($data2,",");
$data2.="],";
}
$data2=rtrim($data2,",")."]";
$key2=rtrim($key2.",");
Replace the two JS as before.
data::<?php echo $data2; >,
labels::<?php echo $key2; >,
key::<?php echo $csvkey; >,
Obviously, there are times when there is a need to do multiple stacked bar group by month. I will leave it to you to figure out. Hint:- Third level array.
Wednesday, April 20, 2016
Javascript Charts
After playing with Filemaker charts and found it limiting in its use, I decided to change to Web based charts. The first concern is what language to use. PHP has been used to do a lot of things for me thus it is the only choice.
The idea is not to create graphics charts from PHP. It will take considerable processing and data transfer size. Therefore, client side charting is the choice. Javascript is the only scripting language on a browser that does not require plugin so it will do.
The last thing to consider is what type of graphics to use to draw the chart. I have used SVG before to create charts. It is nice but I would like to make use of HTML5 canvas element to do it instead. So I finally settled with canvas graphics.
PHP can talk to javascript via AJAX. I too have done it before but the chart I am doing is not real time dynamic data. Thus, PHP is used to create javascript code. There isn't much javascript code to generate to create a chart if you use a javascript chart module that is easily available.
There are plenty of Javascript charts available. Some offer 90 plus type of charts. Since the requirement is probably just Line, Bar, and Pie, The consideration is to get the smallest size module to do the simple work.
Most popular Javascript charts is actually using HTML although the name is Javascript Chart. They even use ".js" as file name. I find it troubling as they actually requires access to the remote site to get the JS source. It also uses "crossorigin" links to JS source. The worst of all is that even the JS file cannot be downloaded locally. Three of the most popular JS chart module I tried cannot even be run on local directory.
I did a considerable search around internet and finally settled with Rgraph. It is a true JS library module and can be downloaded to run locally. The graphic is simple and not as elegant but it works.
The user JS to generate a charts is very simple. You can see it as below
All you need to do is change the "data" and the "labels" option. Getting PHP to generate the two parameter is very easy.
Construct the data in the appropriate format in php and use the following line to replace the data line in JS.
data:<?php echo $data; ?>,
The other change is the Labels line
labels:<?php echo $label; ?>,
That's all. The chart will come out beautifully.
If you want to get the chart to be much more interactive and vibrant, the Rgraph documentation will show you very much more options to set the graphs. Below is a picture of a donut pie chart from the Rgraph examples above.
The idea is not to create graphics charts from PHP. It will take considerable processing and data transfer size. Therefore, client side charting is the choice. Javascript is the only scripting language on a browser that does not require plugin so it will do.
The last thing to consider is what type of graphics to use to draw the chart. I have used SVG before to create charts. It is nice but I would like to make use of HTML5 canvas element to do it instead. So I finally settled with canvas graphics.
PHP can talk to javascript via AJAX. I too have done it before but the chart I am doing is not real time dynamic data. Thus, PHP is used to create javascript code. There isn't much javascript code to generate to create a chart if you use a javascript chart module that is easily available.
There are plenty of Javascript charts available. Some offer 90 plus type of charts. Since the requirement is probably just Line, Bar, and Pie, The consideration is to get the smallest size module to do the simple work.
Most popular Javascript charts is actually using HTML although the name is Javascript Chart. They even use ".js" as file name. I find it troubling as they actually requires access to the remote site to get the JS source. It also uses "crossorigin" links to JS source. The worst of all is that even the JS file cannot be downloaded locally. Three of the most popular JS chart module I tried cannot even be run on local directory.
I did a considerable search around internet and finally settled with Rgraph. It is a true JS library module and can be downloaded to run locally. The graphic is simple and not as elegant but it works.
The user JS to generate a charts is very simple. You can see it as below
var pie = new RGraph.Pie({
id: 'cvs3',
data: [4,8,6,3,5,2],
options: {
shadow: true,
shadowOffsety: 7,
shadowBlur: 25,
strokestyle: 'rgba(0,0,0,0)',
labels: ['Henning','Louis','John','Pete','Lucy','Fred'],
clearto: 'white',
variant: 'donut3d',
labelsSticks: true,
labelsSticksLength:25,
radius: 100
}
}).draw();
All you need to do is change the "data" and the "labels" option. Getting PHP to generate the two parameter is very easy.
Construct the data in the appropriate format in php and use the following line to replace the data line in JS.
data:<?php echo $data; ?>,
The other change is the Labels line
labels:<?php echo $label; ?>,
That's all. The chart will come out beautifully.
If you want to get the chart to be much more interactive and vibrant, the Rgraph documentation will show you very much more options to set the graphs. Below is a picture of a donut pie chart from the Rgraph examples above.
Tuesday, April 19, 2016
Filemaker Chart vs Web Javascript chart
Recently have issues with Filemaker chart thus have to switch to web based charts. There are quite a number of similarities and oddities. The following is the comparison.
You can see that Filemaker charts are for easy creation but is fixed in most features. It is not flexible at all compared to Web Javascript charts. Both caters to specific group of people and interest.
Filemaker | Web |
---|---|
Uses tables | Uses variables |
Forms data from table with data pre fetched from SQL result | Forms data direct from SQL result |
Charts Preformed | Charts can be defined at run time |
Number of legends fixed | Number of legends determined from runtime |
Max number of legend fixed | No Max number of legend |
Max number of data rows not fixed | Max number of rows not fixed |
Titles, X,Y labels prefixed | Determined during runtime although can be prefixed |
Chart type prefixed | Chart type can be changed runtime |
Interactive chart | Interactive chart |
Data values can be displayed | Data values can be displayed |
Number of chart types limited | Number of chart types depends on the module writer. Some can have 90 plus chart types |
No time lapse display of chart data | Have time lapse display of data |
Charts module fixed | Can practically create the chart from scratch. |
Not resizable during run time | Can auto resize or changed during runtime |
Color prefixed | Color changeable during runtime if needed |
Options setting prefixed | Options totally changeable runtime. |
Events trigger not available | Events trigger available depends on module writer. |
Chart data can be added/removed runtime | Chart data can be added/removed runtime |
Must use Filemaker to view chart | Charts can be rendered in any web programming language that can work with javascript and have a graphics display capability. |
Expensive. | Can be totally free. |
Charts formed by fix app setting | Plain javascript text setting. |
Easy to do even with novices | A big learning curve especially when you create chart from scratch |
Standardized | Way too flexible until it is scary |
You can see that Filemaker charts are for easy creation but is fixed in most features. It is not flexible at all compared to Web Javascript charts. Both caters to specific group of people and interest.
Monday, April 18, 2016
Web Site Database browsing in pages
On a web page, the displaying of large quantities of data takes a lot of time for the server to deliver. It is therefore usual for web masters to show the data in pages where at any one time there is a limited number of records shown.
SQL has such a thing called LIMIT or ROWNUM. It basically limits the number of records retrieved from the database. Obviously to get the next page you need to know what is the last record retrieved. This means that you need to define OFFSET after the LIMIT.
This way of paging works quite well. The only problem is that every request means the database has to retrieve the SQL request again then go down to the OFFSET record then show the number of records set by LIMIT. If you have millions of records retrieved in this way then it is obviously process wasting.
There are some who advocate using a sequential incremented unique field as the offset instead. It will be something like this
SELECT * from table where uniquefield > xxx LIMIT 100
It has to remember the last record retrieved and replace the value xxx on the next page. However, this will work only for paging forward. Normally paging will allow forward, backward or start from a specific page. This can only be done with OFFSET.
SQL has such a thing called LIMIT or ROWNUM. It basically limits the number of records retrieved from the database. Obviously to get the next page you need to know what is the last record retrieved. This means that you need to define OFFSET after the LIMIT.
This way of paging works quite well. The only problem is that every request means the database has to retrieve the SQL request again then go down to the OFFSET record then show the number of records set by LIMIT. If you have millions of records retrieved in this way then it is obviously process wasting.
There are some who advocate using a sequential incremented unique field as the offset instead. It will be something like this
SELECT * from table where uniquefield > xxx LIMIT 100
It has to remember the last record retrieved and replace the value xxx on the next page. However, this will work only for paging forward. Normally paging will allow forward, backward or start from a specific page. This can only be done with OFFSET.
Monday, April 04, 2016
How to use a script to create data for a Filemaker Chart
In my previous post on Filemaker Charts, I touched on how to create a table and use it to create charts. In daily operation, the data are actually daily transactions. it is never meant for charts. How then could we transform the data into charts. It is easily done in Excel where user can create summaries to be used in charts. There is a summary in Filemaker too but it cannot be used for charts.
Here I propose using scripts to populate a summary table from a details table. The example code will use Filemaker Charts as an example.
The first thing to fill is "Months" field. Create a calculated text field in the main table and call it "YearMonth". It is necessary to add year as the data may span a number of years. Use the formula below as calculation assuming the field that shows the date of record creation is called CreateDate.
Year(CreateDate) & Case(Month(CreateDate) < 10;"0" & Month(CreateDate); Month(CreateDate)
The above will generate a text like "201604" for current month. It is necessary to insert "0" for single digit month so that the sequence of the data created will be correctly done.
Create the summary table and chart according to examples shown in Filemaker Charts. Create a script called "Summary".
Usually a summary table will pull the data for the entire last year. So the script will start with getting the year.
Set Variable($year;Year(Get(CurrentDate)-1
With the year, append the month value in a loop like below
Set Variable($mth;1)
Loop
If($mth < 10)
Set Variable($ym; $year & "0" & $mth)
else
Set Variable($ym; $year & $mth)
End If
New Record/Request
...
Set Variable($mth;$mth+1)
Exit Loop If($mth>12)
End Loop
The above script only set the loop to get the correct YearMonth value in 12 loops. We need to fill the "Month" field in the summary table. The following script assume you are already in the summary table layout using summary table as database. The subsequent scripts are to be inserted in the line before "Set Variable($mth;$mth+1)" represented by "..."
Set Field(Summary::Month;$ym)
The next task is to fill SiteA, SiteB, and SiteC with the correct summary data from the sales data field "TotalSales". Well, you guess it right, we will use ExecuteSQL function.
Set Field(Summary::SiteA; ExecuteSQL("SELECT Sum(TotalSales) FROM MainTable WHERE SiteLocation = 'SiteA' AND YearMonth=?";"";"";$ym)
Repeat it for SiteB and SiteC.
Run the script and you will get 12 records with the completed sales figure for last year. Your chart will then be able to show the yearly sales figure for the three sites.
A reminder: You need to delete all records of previous data in summary table. Filemaker Charts does not have the facility to define which data to use in the table. Its useless to set a filter as it only applies while the table is in view.
A suggestion is to copy the data into a history record of the yearly performance table. Extract the necessary data back into summary table to show the yearly figure for the year you want to see the chart.
One last thing, The SQL is a very simple one. You could extract the whole year data for all three sites in just one ExecuteSQL
Set Variable($data; ExecuteSQL("SELECT YearMonth,SiteLocation,Sum(TotalSales) FROM MainTable WHERE YearMonth LIKE '" & $year & "*' GROUP BY YearMonth, SiteLocation" ;"";",";)
Use a loop to extract the various rows using GetValue($data;$loop) then extract each item by replacing "," with "¶" then use GetValue to extract the items.
The complex SQL method only useful if you extract just the sales figure. In many situations you need to get more result than that. Usually they use different criteria like TotalSales > 1000000, Total Sales >100000000. One SQL will not be able to extract such criteria and it will be difficult to update the table if you use more than one SQL. Since the first SQL will fill all the 12 records already. You will then have to use filter to choose the right record then add the subsequent SQL result into the correct record.
It is impossible to use ExecuteSQL to update the records. ExecuteSQL does not allow Insert or Update (3rd party SQL plugin does have this capability). It is easier to use simple SQL and then create a record to fill the appropriate fields with the correct SQL result with the resultant multiple SQL that loads the system runtime. The choice is up to you.
Here I propose using scripts to populate a summary table from a details table. The example code will use Filemaker Charts as an example.
The first thing to fill is "Months" field. Create a calculated text field in the main table and call it "YearMonth". It is necessary to add year as the data may span a number of years. Use the formula below as calculation assuming the field that shows the date of record creation is called CreateDate.
Year(CreateDate) & Case(Month(CreateDate) < 10;"0" & Month(CreateDate); Month(CreateDate)
The above will generate a text like "201604" for current month. It is necessary to insert "0" for single digit month so that the sequence of the data created will be correctly done.
Create the summary table and chart according to examples shown in Filemaker Charts. Create a script called "Summary".
Usually a summary table will pull the data for the entire last year. So the script will start with getting the year.
Set Variable($year;Year(Get(CurrentDate)-1
With the year, append the month value in a loop like below
Set Variable($mth;1)
Loop
If($mth < 10)
Set Variable($ym; $year & "0" & $mth)
else
Set Variable($ym; $year & $mth)
End If
New Record/Request
...
Set Variable($mth;$mth+1)
Exit Loop If($mth>12)
End Loop
The above script only set the loop to get the correct YearMonth value in 12 loops. We need to fill the "Month" field in the summary table. The following script assume you are already in the summary table layout using summary table as database. The subsequent scripts are to be inserted in the line before "Set Variable($mth;$mth+1)" represented by "..."
Set Field(Summary::Month;$ym)
The next task is to fill SiteA, SiteB, and SiteC with the correct summary data from the sales data field "TotalSales". Well, you guess it right, we will use ExecuteSQL function.
Set Field(Summary::SiteA; ExecuteSQL("SELECT Sum(TotalSales) FROM MainTable WHERE SiteLocation = 'SiteA' AND YearMonth=?";"";"";$ym)
Repeat it for SiteB and SiteC.
Run the script and you will get 12 records with the completed sales figure for last year. Your chart will then be able to show the yearly sales figure for the three sites.
A reminder: You need to delete all records of previous data in summary table. Filemaker Charts does not have the facility to define which data to use in the table. Its useless to set a filter as it only applies while the table is in view.
A suggestion is to copy the data into a history record of the yearly performance table. Extract the necessary data back into summary table to show the yearly figure for the year you want to see the chart.
One last thing, The SQL is a very simple one. You could extract the whole year data for all three sites in just one ExecuteSQL
Set Variable($data; ExecuteSQL("SELECT YearMonth,SiteLocation,Sum(TotalSales) FROM MainTable WHERE YearMonth LIKE '" & $year & "*' GROUP BY YearMonth, SiteLocation" ;"";",";)
The complex SQL method only useful if you extract just the sales figure. In many situations you need to get more result than that. Usually they use different criteria like TotalSales > 1000000, Total Sales >100000000. One SQL will not be able to extract such criteria and it will be difficult to update the table if you use more than one SQL. Since the first SQL will fill all the 12 records already. You will then have to use filter to choose the right record then add the subsequent SQL result into the correct record.
It is impossible to use ExecuteSQL to update the records. ExecuteSQL does not allow Insert or Update (3rd party SQL plugin does have this capability). It is easier to use simple SQL and then create a record to fill the appropriate fields with the correct SQL result with the resultant multiple SQL that loads the system runtime. The choice is up to you.
Friday, April 01, 2016
Is Android screen locking App useful?
Tried an application on my android that have a lock screen widget floating on the screen. It can work as purposed. I do face a few difficulties.
It usually failed right after I lock it and then unlock although the widget still appears after the message. It is quite annoying to see the message popping out. It seems to be intermittently disappearing also. Moreover it interferes with my keyboard widget. My keyboard keep goes intermittently missing while I am typing.
Finally give up and unset the floating lock screen icon and used shortcut icon instead. It worked only on the home screen but I usually close all app before doing manual screen lock so it still works fine for me.
Some might ask why I want to use an app to lock screen. Well, On off button is a mechanical device. It will fail if used too often. So rather than clicking it twice every time I want to use the phone, the app will remove one click. That is half the number of clicks.
Subscribe to:
Posts (Atom)