Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Browse - Can I change the sort order on the fly? 1

Status
Not open for further replies.

emaduddeen

Programmer
Mar 22, 2007
184
US
Hi Everyone,

I have a browse using the abc templates. It has an entry field as the locator. The locator is a local field. "Enable Sort Header" is turn on.

Can you tell me how to change the sort order using code so the user does not need to click on the headers?

Thanks.
Emad
 
Hi Emad,

I spent a LITTLE time researching this.
Apparently CLASS(SortHeaderClassType) comes into play.

A quick search shows that the code for the class is in %cwroot%\libsrc\brwext.inc & .clw

In the generated code for the example: in abcbrws.app's BrowseEmpColSort I see a derived method for .QueueRestorted(STRING)

I tried looking at the generated code:
I see a call to .ReplaceSort(pString)
But I was unable to convince myself that it would help.

I tried to understand what should be in the argument.
I tried looking at .MousePressed in brwext.clw
Hmmm,

I noticed some in code documentation in brwext.clw near .SetSortFromString I see:

! The string should be in this format
! [+|-]Field,[+|-]Field,[+|-]Field,.....
! If the field is not found in the browse it will not be part of the sort

As I look at it more, seeing .LoadSort it shows restoring the sort from the registry or an .INI This seems like a good bet.

I'd try calling .SetSortFromString(sNewSort)

Where sNewSort follows the above format.
And where Field matches a PROP:Label in your view

HTH,
Mark Goldberg
 
Hi Mark,

I will try it out.

If I combine that with a BrowseObject.ResetFromBuffer() after placing some text into an entry control then doing a set() and next(), will it make the highlight bar on the browse position itself to the closest match in the new sort order?. That is why I was wanting to change the sort order on the fly.

My idea was this: If the entered text in the entry control is not found in the customer table as a phone number then the code would try to find the closest natch as the last name of the customer.

Truly,
Emad
 
Hi Mark,

I tried it out and the sort moved over to the correct column in the browse and the rows sorted in the correct order.

All I need to do to complete this is to find out how to make the highlight bar go to the closest phone number match.

Here is the code I have so far:

Code:
BRW1::SortHeader.SetSortFromString('CUS:MainNumber')

Clear (CUS:Record)

Set (CUS:KeyPhone, CUS:KeyPhone)
Next (Customers)

BrowseCustomers.ResetFromBuffer()

Select (?BrowseCustomersList)

Truly,
Emad
 
Hi Emad,

You forgot one line of code

Code:
!Your Code
!------------
Clear (CUS:Record)

Set (CUS:KeyPhone, CUS:KeyPhone)
Next (Customers)

Code:
!Revised Code
!------------
Clear (CUS:Record)

!vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
CUS:MainNumber = LocatorValue 
!--- note: I'm guessing about the components of KeyPhone
!^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Set (CUS:KeyPhone, CUS:KeyPhone)
Next (Customers)

HTH,
Mark
 
Hi Mark,

oooooooooooooooooooooooooooppppppppppppppppppppsssssssssssss!!!!!!!!!!!

That's the most import part. I don't know how I overlooked that one.

Glad you caught that one.

Thanks so much.

Truly,
Emad
 
Hi Mark,

I put this code in but the only thing that changes is the sort order and no movement of the highlight bar.

Maybe there is something else that will activate the moving of the highlight bar.

Thanks.
Emad

Code:
BRW1::SortHeader.SetSortFromString ('CUS:MainPhone')

Clear (CUS:Record)

CUS:MainPhone = LOC:Locator

Set (CUS:KeyPhone, CUS:KeyPhone)
Next (Customers)

BrowseCustomers.ResetFromBuffer()

Select (?BrowseCustomersList)
 
Hi Emad,

Try revising the code to :

Code:
Clear (CUS:Record)

CUS:MainPhone = LOC:Locator

Set (CUS:KeyPhone, CUS:KeyPhone)
Next (Customers)

BrowseCustomers.ResetFromBuffer()

BRW1::SortHeader.SetSortFromString ('CUS:MainPhone')

Select (?BrowseCustomersList)

i.e. set the sort order after finding the record.

OR

you could try using the SetShadow method of the locator object of the browse i.e.

Code:
BRW1::SortHeader.SetSortFromString ('CUS:MainPhone')

BrowseLocatorObject.SetLocatorField(CUS:MainPhone)

BrowseLocatorObject.SetShadow(LOC:Locator)

BrowseLocatorObject.UpdateWindow

I have not tried the code shown above.

Regards
 
Hi ShankarJ,

I tried both but they had the same results by only setting the sort order and not moving the bar.

Thanks.
Emad

Code:
BRW1::SortHeader.SetSortFromString ('CUS:MainPhone')

BRW1::Sort0:Locator.SetLocatorField(CUS:MainPhone)

BRW1::Sort0:Locator.SetShadow(LOC:Locator)

BRW1::Sort0:Locator.UpdateWindow
 
Hi Emad,

Is your BrowseObject.RetainRow property set to True?

Regards
 
Hi ShankarJ,

I tried these but I get a compile error:
Field not found: RetainRow

Code:
BRW1::View:Browse.RetainRow
BRW1::View:Browse.RetainRow()
Queue:Browse:1.RetainRow
Queue:Browse:1.RetainRow()

The code was unfamiliar to me so I tried all of these different variations.

I am sure I was looking at the wrong location for what the browse object really is.

Thanks.
Emad

 
Hi Emad,

It is a property and hence the usage is :

BrowseObject.RetainRow = True

Depending on the global settings you have set for Browse objects, this could be ON or OFF by default. It is normally suggested that it be turned OFF for SQL databases but I always turn it ON.

Regards
 
Hi ShankarJ,

I went to the global properties then classes then browser but did not find a checkbox to fill in for RetainRow.

If this is a code only thing, can you tell me how to locate my BrowseObject ?

Thanks.

Truly,
Emad
 
Hi Emad,

Go to Global -> Classes -> Browser -> Configure. It is in the Database Optimizations group box.

Also, you could try :

BRW1::SortHeader.SetSortOrder (3)

instead of

BRW1::SortHeader.SetSortFromString ('CUS:MainPhone')

if CUS:MainPhone is the 3rd column in the List Box.

Remember my posting in reply to your query on finding the current sort order.

Regards
 
Hi ShankarJ,

Thanks for the mapping to the checkbox. I noticed it was already selected.

I tried BRW1::SortHeader.SetSortOrder (3) but it had the same effect as using BRW1::SortHeader.SetSortFromString ('CUS:MainPhone')

And yes the phone was column number 3. That was a good guess!

I still can't figure out how to make that highlight bar move. If I comment out all the code and click on the phone header and enter data into the locator everything works ok but I was hoping to let the user first start the browse with the sort order as the last name which I can now do. If the name does not find a match we wanted to switch the sort order to phone (that works to) then make the locator move the highlight bar to the closest match.

Thanks everyone for all the time you are taking to help us.

Truly,
Emad
 
Hi Emad,

Is LOC:Locator set as the locator override control in the browse properties??

If yes, you could just try :

BRW1::SortHeader.SetSortOrder (3)

CHANGE(?LOC:Locator, '....')

POST(EVENT:Accepted, ?LOC:Locator)

Regards
 
Hi ShankarJ,

The post event won't for me because the code I am using is in the Accepted embed of the locator field.

The locator field is used instead of the default one.

Truly.
Emad
 
Hi Everryone,

I have some thoughts on what may be a work-around.

I found out that BRW1::SortHeader.SetSortOrder (3)
and BRW1::SortHeader.SetSortFromString ('CUS:MainPhone') both throw something off somehow. I also found out that if I don't use one of those statements, the locator works fine (clicking on the header and filling in the locator, followed by the tab key)

Is there a way that I can use code to emulate the clicking of the header buttons on the browse? At least if I can do that, I know that it should be fine to test the results and code accordingly.

Truly,
Emad

 
Hi Everyone,

Solution (well almost) was found.

I had to turn off "Enable Sort Header" and had to select "None" for the locator. I did however keep the local control for what will be a simulated locator. In the "Control Events" -> "?BrowseCustomerList" -> "All Events" embed I placed this code:

Code:
! When user presses a key in listbox, put it in the first locator entry control.
!-------------------------------------------------------------------------------

If (Keycode() >= 65 And Keycode() <= 90) Or (Keycode() >= 49 And Keycode() <= 58) |
Then
   LOC:Search = Chr (Keycode())

   Select (?LOC:Search)

   PressKey (EndKey)
End

I placed this into the "Control Events" -> "?LOC:Search" -> "Accepted" embed of the control to be used as the simulated locator:

Code:
! Simulate an entry locator on phone, then on name.
!--------------------------------------------------

Clear (Customers)

! Try to find the value entered as a phone number.
!-------------------------------------------------
CUS:MainPhone = LOC:Search

Get (Customers, CUS:KeyPhone)

If Not Error () |
Then
   ! Pull the row based on name and phone because the list key is in that order.
   !----------------------------------------------------------------------------
   Get (Customers, CUS:KeyCustomerNamePhone)
Else
   ! Then phone was not found. Try to find closest match by surname.
   !----------------------------------------------------------------
   Clear (Customers)

   CUS:Surname = LOC:Search

   Set (CUS:KeyCustomerName, CUS:KeyCustomerName)
   Next (Customers)
End

! Show the search result in the list.
!------------------------------------
BrowseCustomers.ResetFromBuffer()

I have 2 keys defined on the customer table. One is on just the phone and the other is on the name then on the phone. The browse is sorted on the name then the phone.

Now the user can enter a phone number and if that number is not found the program assumes the user wanted a surname search and the highlight bar will be on the closest match.

Thanks for all your help in trying to find a solution. I is really appreciated.

Truly,
Emad
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top