Forum Replies Created
-
AuthorPosts
-
jaska_lee
Participantif I don’t make the change to construct method, it goes like this(please see the screenshot) and i couldn’t get it align with the rest textboxes.
i see the point of using ‘CheckBoxPair’, however, i actually prefer no rectangle on prompt when clicked.
thanks for the tips andrew.jaska_lee
Participantthanks andrew, I have modified two standard objects and it now seems to be working as I expected.
1) CheckBoxPairControl
Following changes make the text show on the left for CheckBox control.PassthruController{
Name: 'CheckBoxPair'
New(prompt, checkbox, hidden = false) // old: (checkbox, prompt, hidden = false)
{
super(.layout(prompt, checkbox, hidden)) // old: (checkbox, prompt, hidden)
c = .Horz.GetChildren()
// old
//.box = c[0]
//.text = c[2]
//.Ymin = .box.Ymin
//.Top = .box.Top
// old
// new
.text = c[0]
.box = c[2]
.Ymin = .text.Ymin
.Top = .text.Top
// new
}
layout(prompt, checkbox, hidden) //old: (prompt, checkbox, hidden)
{
text = Object('Static', prompt, notify:, hidden: hidden)
for m in #(font, size, weight)
if checkbox.Member?(m)
text[m] = checkbox[m]
//old: return Object('Horz', checkbox, #('Skip', 3), text)
return Object('Horz', text, #('Skip', 3), checkbox)
}
Get()
{
.box.Get()
}
Set(val)
{
.box.Set(val)
}
SetFocus()
{
.box.SetFocus()
}
BnSetFocus()
{
.text.DrawFocusRect(true)
}
BnKillFocus()
{
.text.DrawFocusRect(false)
}
Static_Click()
{
if .box.GetEnabled()
{
.box.SetFocus()
.box.Set(not .box.Get())
.box.BN_CLICKED()
}
}
}2) Construct method in Control object
On Access control, I could not make the text align with the rest of the textboxes. But if I comment out the code concerning ‘prompt isn’t greyed’ for CheckBox, it aligns with others nicely and prompt isn’t greyed in protect mode. Is it safe to do it like this?Construct(@x)
{
if (x.Size() is 1 and x.Member?(0) and Object?(x[0]))
x = x[0]
if (x[0] is 'NoPrompt' and String?(x[1]) and x[1] =~ "^[_a-z]")
{
c = x
x = Datadict(x[1]).Control.Copy().Add(x[1] at: 'name')
for m in c.Members()
if String?(m)
x[m] = c[m]
}
else if (String?(x[0]) and x[0] =~ "^[_a-z]")
{
name = x[0]
dict = Datadict(name)
x = dict.Control.Copy()
hidden = false
if .Custom isnt false and .Custom.Member?(name)
{
x.Merge(.Custom[name])
hidden = .Custom[name].GetDefault('hidden', false)
}
x.name = name
if "" isnt prompt = Prompt(name)
{
//if x[0] is 'CheckBox'
//x = Object('CheckBoxPair', x, prompt, hidden: hidden)
// need this so prompt isn't greyed when protected
//else
x = Object('Pair', Object('Static', prompt, hidden: hidden), x)
}
}
_parent = this
_ctrlspec = x
ctrl = Construct(x, "Control")
if (ctrl.Name > "")
this[ctrl.Name] = ctrl
return ctrl
}jaska_lee
Participantah ok, I didnt notice the ‘access’ button after right click. Thanks for pointing that out.
It would be nice to just let the default dropdown button do the task.
I personally think that may offer a more consistent and user friendly experience from a UI point of view.
Anyway, just my own opinion.jaska_lee
ParticipantThere are pros and cons for both of them:
pros:
1) the first approach is fast and easy during calculation, as it pulls out the totals which are physically stored.
2) the second approach does not have any physical impact to the database or cause any additional operations. And in real cases, the requirements are specific, like for a certain number of G/L Account in a given period of time. These could help to narrow down the transactions which can be profitable in reality.cons:
1) the first approach is costly to maintain during transaction update. And it has a physical, permanent impact to the database and front end system.
2) the second approach needs to calculate every result from the transactions every time it is needed, which could be very large and slow too.Never mind, I just thought it’s an idea worth a look.
jaska_lee
Participantsorry for not being specific.
There are cases in which I need to do cumulative totals at each date for a given period of time. For instance, G/L Account balance at each date through out the entire fiscal year. Or, Item inventory at each date for a given period of time. The most common approach I have seen in many different systems is to create a kind of index table which consists of concerned elements, e.g.
"GL Account No." Date Balance
1100 09/08/2014 10
1100 09/09/2014 20
1100 09/10/2014 30
....
1200 09/08/2014 10
1200 09/09/2014 20
1200 09/10/2014 30
....Whenever there is transaction happening to G/L Account No, we try to maintain this index sum table. So that we can pull it out later for cumulative balance reporting. The same logic could be implemented for other similar requirements. The problem with this approach is that by the time it goes, this table becomes increasingly large and very “expensive” to maintain. Sometimes, it gets so bad that the system becomes really slow and we cant afford to maintain this table during transaction update. And, technically, it can be quite challenging to write the code to maintain this table, especially when the criterio becomes complex.
There is a different approach which I have seen in another system that is written in C++. It implements a kind of virtual date table like a built-in date calender which has a table structure like this:
Date Name
01/22/0001 Monday
01/23/0001 Tuesday
01/24/0001 Wednesday
01/25/0001 Thursday
01/26/0001 Friday
01/27/0001 Saturday
01/28/0001 Sunday
...
01/01/9998
01/01/9999The data in this table is not physically stored in the database but dynamically populated in memory. In this case, if I want to calculate G/L Balance at date, I simply do a G/L Account left join Date, then using this G/L Account No. and each specific date, one can easily filter out the transactions and calculate the totals accordingly. This way, there is no need to create or maintain any additional tables with totals. And it is easy to change the logic of calculation in case criterio changes without physically affecting the database, in fact, with Rules, one can just create as many derived columns as they need against with this Date table and attach them on fly for different needs.
jaska_lee
Participantthanks for the information andrew. I have added this feature into a copy of the standard KeyControl. It works well for me. Although, maybe I shouldn’t have gone that way as it turned out to be quite complex, involving quite a few other standard objects. I just cant help myself :).
Now, I still have a small issue. When the item no. changes, the existing unit of measure code assigned for previous item no. could no longer be valid for the new item no. How could I make UOM code show as red? When i type invalid data in this control, system shows this field as red, preventing user from saving the record. I want system to do the same when it becomes invalid due to item no. changes.
Thanks
jaska_lee
Participanthi both, thanks indeed for your suggestions.
j_ferguson: your workaround could indeed be implemented, but i am very much keen to find a more simplified solution.
andrew: I have already used your suggestion in a different case. The disadvantage is that you end up seeing only one field without knowing what’s inside of other fields which provide more relevant information to make the selection. Also, the possibility of modifying the original table through ‘access’ button is gone.
I would like to modify KeyControl or create a different control my own to do following:
Modifying the whereField or restrictions to be an object #((‘sourcefield1′,’=’,currenctfield1),(‘sourcefield2′,’>’,currenctfield2),…). sourcefield is passed in as field name of the source table which will be filtered on and currentfield is passed as filter value from current table. This way, the rename command in the query could also be avoided.I also would like to deactivate key checks because i don’t see them too necessary here, except providing sorting and record identification which is not my concern in most of the cases.
Is that possible?thanks
jaska_lee
Participanthi andrew, thanks for the tip indeed!
jaska_lee
Participantok i got it,
IdControl
{
New()
{
super(query: "item",
field: 'item_No'
columns: #(item_No,
item_Name,
item_Price)
)
}
}jaska_lee
Participanthi andrew, that worked. Thanks very much for your help.
jaska_lee
Participantnice, a new class “GetSystemDefaultLocaleName” worked out,
dll long Kernel32:GetSystemDefaultLCID()
It returns 1054 which matches “Language for non-Unicode programs” setup according to Microsoft language id definitions.
http://msdn.microsoft.com/en-us/goglobal/bb964664.aspxthanks!
jaska_lee
ParticipantHi Andrew,
In order to compare “Language for non-Unicode programs” under control panel from both client and server, I first tried to retrieve the language code. But i couldn’t find the right constant to pass into method:
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE.SLONGDATE, buf = Buffer(80), 80)
There is a website which provides some constants and I have tried most of them but it didnt give me what I wanted.
Any suggestion?
Thanks
jaska_lee
ParticipantThis happened a few weeks back when I tried to flip around between English and Thai language setup. And it happened couple of times. I thought I could always warn the customer to use the same language setup before they login the system, so I gave it a lower priority.
But today, when i try to reproduce the same issue, it does not happen. Maybe I haven’t got the environment setup right.
Nonetheless, this is necessary in my case. When one user is typing unicode language like Thai under Thai language setup, he can type and see Thai characters nicely. But if another user is connecting to the system with a different language setup like English, he wont be able to see or type Thai, the Thai characters are shown as unreadable strings. So, a check to make sure this setup is consistent across all clients makes sense.
I will give it a try later, thanks a lot andrew!
jaska_lee
ParticipantHi Andrew, That worked, thanks a lot for your help!
August 21, 2014 at 2:07 am in reply to: [SVD]How to access current row selection on a browse control #1082jaska_lee
ParticipantHi Andrew,
It is just my idea and may not be necessary for others. Here it is,
When defining an Access/Browse control inside of a controller, normally the developers would need triggers such as
On_Insert, On_Delete, On_Modify on the record level to interact with user actions to perform data validation and other type of business logic. Furthermore, the developers would also need triggers such as On_Validate on a field level to interact with users to do similar tasks.Mostly of the similar triggers are already provided in suneido controls, but require additional actions to be added into controller. Sometimes, it takes a lot of time and effort to figure out how they should be defined or if they exist at all. So my idea is that, it would be a good practice to add them into the controller as a standard step when defining controller.
When I look at them later, I can see immediately what triggers are available and use them accordingly. It is also easier for other developers to do continuous support and modification.
-
AuthorPosts