Checkbox Columns

December 1, 2010

If you need to add a checkbox column to an SLX LAN datagrid, here are the steps (after you’ve already set up the grid’s SQL/Layout properties):

  1. On the grid’s Properties page, clear the ReadOnly and RowSelect properties
  2. Go into the Columns property of the grid (i.e., click on the ellipses button for the property)
  3. Right-click on the column you want to set to a checkbox, and select Change Column Type…
  4. From the combo box, select Check, and OK
  5. Right-click on the column again, and select Properties…
  6. Make sure the Read-Only box is cleared
  7. For each of the other grid columns in turn, set the Read-Only property box to be checked (assuming you want the checkbox column to be the only editable column on the grid)

This is documented somewhere, right?

Yeah: Right here. 🙂


Select a DataGrid Row by its Number

June 12, 2010

This is the kind of thing that’s too easy to forget (or lose track of):

To select a row in a grid by its number:

Dim WScript, i, NumberOfRow

If Not Datagrid1.Focused Then DataGrid1.SetFocus
Set WScript = Application.CreateObject("WScript.Shell")

For i=0 To NumberOfRow-1
     WScript.SendKeys "{DOWN}"

Set WScript = Nothing

GridName.Selection.Item(i) contains the value of the DataGrid’s Key Field for the selected row.

If you want to access a selected node, you should use GridName.SelectedNodes.Item(i) .

If you want to get the value for any field in a selected row, then use GridName.GetFieldValue(GridName.Selection.Item(i), FieldName).

On the topic of SendKeys, there’s also this:

Dim objSh

Set objSh = CreateObject("WScript.Shell")

' Example sending TAB key
objSh.SendKeys "{TAB}", False

' Example sending ALT+F5
objSh.SendKeys "%{F5}", False

' etc

Set objSh = Nothing

Tips and Tricks – IV

May 20, 2010

Tips and Tricks IV: The Voyage Home.

  • SalesLogix performance will suffer with cursors being left open. If you are coding in SalesLogix it is very important that you close your Recordsets, setting your Recordsets to Nothing is NOT enough, you should always have code like this:
If oRS.State = 1 Then
End If
Set oRS = Nothing
' Need to restrict the Lookup to records where
' Account.Type='Customer' and Account.Location='US'):
LookUpName = "Account:Account"
RestrictAlways = True
Lookup.LookupRestrictField = "TYPE'"
Lookup.LookupRestrictOp = "='Customer' and LOCATION="
Lookup.LookupRestrictValue = "US"
  • Create a “.txt” file. Rename the file to “.udl”. When you double-click on the file it will display the standard connection designer!

And lots of good stuff from Ryan Farley’s site:

Tips and Tricks – II

May 5, 2010

More Tips and Tricks….

  • To execute a method of a control on another form:
Set oForm = Application.Forms("Ticket:Support Ticket Widgets")
  • You can turn off “Open project at startup” via the Tools > Options menu in Architect
  • To delete an old version of a plugin, right-click on it in Plugin Manager, select Properties…, and remove the checkmark from the Read Only checkbox. Click OK. Then press the Delete key. You will be prompted for whether you are sure that you want to delete the plugin. Click Yes
  • If you set the ShowGroupPanel property of a DataGrid to True, it will create a blank (dark gray) area above the grid’s table. You can then drag any column header from the grid into that area, allowing the user to group by that field
  • The SysInternals Suite from Microsoft contains, among many other goodies, a DebugView utility. If you put lines like
Application.Debug.WriteLine Err.Number
Application.Debug.WriteLine "Creating Recordset"
    into your SLX scripting, and then run the dbgView.exe, you can read the WriteLine’s there

  • The SLX Mail Merge engine calls the System:SLX Mail Merge OnCustomFieldName script whenever it encounters a custom field in a (Word template) document. “This allows us to insert whatever data we need to in the document at merge time” (Stephen Redmond)
  • The recommended way of creating new recordsets in SLX is to use this function:
  • Using DoEvents in SLX VBScripting works fine, but there’s also Application.DoEvents
  • To programmatically create a new activity, use the Application.Activities class:
Set Act = Application.Activities.Add(atPhoneCall)
Act.AccountID = strAccountID
Act.StartTime = DateAdd("d", 7, Now)
  • The “Insert:ContactAccount” function, for inserting new Accounts/Contacts, calls the System:ChooseContactAccount plugin
  • When closing a form via Application.BasicFunctions.CloseCurrentView blnValue, passing True causes the form to be closed as if the user clicked the Cancel button; passing False closes the form as if the OK button had been pressed (i.e., also running any validation code before it closes)
  • Use Application.BasicFunctions.GetGroupList(Family, Type) to retrieve a list of either all of the groups available to the current user (Type = 0 returns string names, Type = 1 returns the actual plugin IDs). Use GetGroupSQL to retrieve a particular group’s SQL (by its ID). Use GetGroupIDs to get a handle to the comma-separated list of IDs in a group, and then use GetGroupCount and GetGroupValue (0-based) with that handle to iterate through the list, to parse it out into its individual ID values
  • For parsing general CSV strings, use CSVCount and CSVField (to get the value in the 1-based position, from 1 to CSVCount)
  • Use GetLineCount and GetNthLine to parse strings where there is a carriage return and line feed separating the values (e.g., from ParseName)
  • GetOwnerName returns the name for a given SecCodeID value
  • To get an OTB path where you can create your own temporary files, use GetPersonalDataPath (SLX already stores copies of reports that are run, or checked out of Architect, in that folder)
  • To attach a new file to an ACO record, use InsertFileAttachment. If you already know the path to the file you want to attach, use InsertFileAttachmentEx instead
  • To transform a string in ISO format (yyyymmdd hh:mm:ss) into a date variable, use ISOToDate
  • In custom code (as opposed to the OTB SLX functionality) and on DataGrids, deleting an Account doesn’t automatically delete its Contact, Opportunities, Activites, or History records, etc. To cause that cascade-deletion to happen, you’ll need to call CascadeDelete strEntity, strEntityID for the parent entity. That will cascade through all of the Joined tables where CascadeDelete is set to “Delete”