The Butter Connection

aka "stanguru.com" and "themargerums.com"

Computer Tips & Help
AS400
PC
Hardware
Programming
Web Development
Virus
Spyware/Malware
Spam
Hoax Don't Spread It
Sports
Cancer
Multiple Sclerosis
Election Stuff
Photography
Handy Links
Interesting
Cool Things
Gamer Stuff
Gallery
Clarion · SQL · SQL Dates · SQL RPG examples · Batch Files

I don't knoow the best way to categorize this so when it gets cluttered, I will reorg it somehow. This section is here b/c I always forget how to do some of this stuff.

 

Wiki on Clarion history - http://en.wikipedia.org/wiki/Clarion_(programming_language)

 

QuickLinks (on this page)

 

Links - external

 


General Un-Categorized

 


WSLDIAL.DLL GPF ...yeah it doesnt exist
http://www.dka.net.au/kb/100023.html

 

 

 

Clarion SQL error - "Connection is busy with results for another hstmt"  "S1000"

"Connection is busy with results for another hstmt" - "S1000"
set /BUSYHANDLING=2  ***default is 3
 
 
in Clarion Help - "Database Drivers and Interfaces", "All SQL Accelerators...", "SQL Drivers strings", "Busy Handling"

 

SQL in Clarion

    ?Button:Print{prop:text} = 'No Stuff to Print'

    sqlfile{prop:sql} =   'select count(*) from YOURFILE where YOURFIELD = ' & PRE:YOURCOMPARE
    if errorcode() then stop(fileerror()).

    buffer(sqlfile, 20)
!    set(sqlfile)
    loop
        next(sqlfile)
        if errorcode() then break.
        if SQLf:f1 > 0
            ?Button:Print{prop:disable} = 0
            ?Button:Print{prop:text} = 'Print the Stuff'
        end
    end

 

Access database in Clarion
-file defs
 database driver = ODBC
 owner = !glo:owner

-in code in the Main procedure...right before it tries to open a file
  glo:owner = 'driver=microsoft access driver (*.mdb);dbq=database1.mdb;'
 
  SETCURSOR(Cursor:Wait)
  OPEN(SQLOpenWindow)
  ACCEPT
    IF EVENT() = Event:OpenWindow
  ! Procedure setup standard formulas
  ! [Priority 7300]

  ! Open Files
  Relate:Divisions.Open                                    ! File Divisions used by this procedure, so make sure it's RelationManager is open
  SELF.FilesOpened = True
! [Priority 7800]
      POST(EVENT:CloseWindow)
    END
  END
  CLOSE(SQLOpenWindow)
  SETCURSOR()


!glo:owner

 

 

 

Clearing a queue - delete all entries in a queue
 -clear(queuename) does not work, do free(queuename) which deletes all entries
 


good descriptive error message on Gets/Puts

if errorcode() then message(clip(LOC:ProcedureApplicationName) & '|myroutine ROUTINE - Error on PUT(myfilename)||PRE:FieldNameonKey : ' & PRE:FieldNameonKey & '.|Error:' & ERRORCODE() & '-' & error() & '|Fileerror:' & fileerrorcode() & '-'& fileerror()) .

if errorcode() then message('Procedure/?OK - Error on get(yourfile, yourkey).|Error:' & ERRORCODE() & '-' & error() & '|Fileerror:' & fileerrorcode() & '-'& fileerror()).

    if loc:DebugIt then message(clip(LOC:ProcedureApplicationName) & '|MyROUTINENAME routine top.|' & '|pre:field : ' & pre:field) .


set a strings text and color
      ?mystringfield{prop:text}      = 'Whazzzup dude'
      ?mystringfield{prop:fontcolor} = COLOR:GREEN   !make sure there is an equate for your color


change colors at runtime
 text
 ?yourstring{PROP:FONTCOLOR} = COLOR:RED !look at the equates.clw to get the color your want
 
 field background color (like to hilite on field error or something)
 ?yourfield{PROP:BACKGROUND} = COLOR:YELLOW



rounding - always round up
 PRE:FIELD = INT(PRE:FIELD2 / 25.4) + 1
 
Get to the history fields when changing a record

***might have to fill it in ThisWindow.init with
History::PRE:Record = PRE:Record

 

for regular field
history::PRE:record.FIELDNAME
 
for field in a group
history::PRE:record.PRE:GROUPLABEL.FIELDNAME
 
***lower case are need to be there, the upper case are your field/label names

 

force addition of record
          ThisWindow.Update
          IF ACCESS:InvoiceHeader.PrimeRecord() THEN RETURN Level:Notify.
          LOOP UNTIL ACCESS:InvoiceHeader.Insert() = Level:Benign
          END !end loop
          GlobalRequest = InsertRecord
          !REL:ReleaseNumber = 0
          UpdateInvoiceHeader()
          ThisWindow.Reset

 

close a file to empty it, if procedure has already opened it

Relate:FILENAME.close()
relate:FILENAME.close() !double close seemed to work
open(FILENAME,12h)
if errorcode()
  message('Error opening FILENAME - ' & errorcode() & '-' & error())
end
empty(FILENAME)
if errorcode()
  message('Error emptying FILENAME - ' & errorcode() & '-' & error())
end
Relate:FILENAME.open()



function creation inside a generated app

  • create the MAP the very top of the DATA section and the function name declaration has to be all the way left
  • this function sends a long and receives a long back
    •  map
      Filesexist   FUNCTION(long),long
       end
  • then before the first procedure, or at the end of the mainline code (in a generated app there is only 1 line of "GlobalResponse = ThisWindow.Run()"
    • FilesExist         function(long store)
      FileQueue          QUEUE(FILE:Queue), PRE(FQ)
                         END
      LOC:ServerPath string(255)
        CODE
          LOC:ServerPath = '\\server\directory\'
          DIRECTORY(FileQueue, CLIP(LOC:ServerPath) & '*.DWN', ff_:NORMAL)
          RETURN(RECORDS(FileQueue))


 

 



RTF Stuff

 

https://metacpan.org/pod/The_RTF_Cookbook

 

RTF in Clarion - C:\clarion6\LIBSRC\rtfctl.clw

 

RTF removal for browse box
create a field on your screen, make it a local var, and hide it
 *loc:rtf1 is the var in example below
create a local field in your list box
 *loc:rtf2 is the var in example below

inside the BRWx.ValidateRecord procedure, after the NOT=Record:OK

!what your doing is:
! moving the field that contains the RTF controls in it to the screen var that is an rtf and hidden
! then using that rtf controls function to remove the RTF controls and put into your field that you put in your browse
! ***still havent found workaround for XPlore template when doing the output to CSV
    loc:rtf1 = FILE:MyRTFField
    display(?loc:rtf1)
    RTFControl21.GetText( loc:rtf2 ,0 ,1024 )


 

RTF - add some text at end of what exists

***name your RTF control class...makes it a little easier to maniplulate rather than number add ":YOURFIELD"

!check for any text in it, if not the start the rtf code

if RTFControl:YOURFIELD.props.length() = 0
PRE:YOURFIELD = '<123>\rtf -' & GLO:Initials & ' ' & format(today(),@d2) & ' ' & format(clock(),@T1) & ' - <125>'
else
PRE:YOURFIELD = PRE:YOURFIELD[1:INSTRING('}',PRE:YOURFIELD,-1,len(clip(PRE:YOURFIELD)) ) - 1] & '\par-' & GLO:Initials & ' ' & format(today(),@d2) & ' ' & format(clock(),@T1) & ' - <125>'
end

 

RTF - position cursor at the end of the text

***the key is to do the display first (or nothing will work)

display(?PRE:YOURFIELD)
select(?PRE:YOURFIELD,RTFControl:YOURFIELD.props.length() )

 

RTF on report - if you need to bold a couple words in a string
add a string to local data and make it text and rtf
populate the field on the report
in the code you cant use the { or } so use the hex of <123> or <125> respectively to assign to a string

so to bold a couple words
rtf: {\rtf Here is your {\b bolded} word.}
clarion: <123>\rtf Here is your <123>\b bolded<125> word.<125>

Example

{\rtf1
{\fonttbl
{\f0\fnil\fprq1\fcharset0 Arial;}
{\f1\fnil\fprq1\fcharset0 Georgia;}
}


this is line 1 with a bold \b word\b0  right here\par
this is line 2 with a fonted \f1\fs28 word\f0\fs17  right here\par
this is line 3 with a sized \fs28 word\fs17  right here\cf2\par
}

 


Path Stuff


check for backslash in path
          if instring('\',SYS:ImageDir,1,len(clip(sys:imagedir))-1) <> len(clip(sys:imagedir))
              message('          Must have \ at end!!!       ','Path Error',ICON:Exclamation)
              cycle
          end !end instring

 

check for path existence
          if not exists(sys:imagedir)
              message('          Directory does not exist.       ','Path Error',ICON:Exclamation)
              cycle
          end !end not exists


strip filename and path off a full path named file

        posstart# = instring('\',rtn:fullfilename,-1,len(clip(rtn:fullfilename))) + 1
        rtn:filename = sub(rtn:fullfilename,posstart#,len(clip(rtn:fullfilename)) - posstart# +1)
        rtn:pathname = sub(rtn:fullfilename,1,posstart#-1)


Directory() note - the queue will not clear unless you clear it yourself 
 
get the path only for where your program is running
    ProgramPath    = sub(command('0'),1,instring('\',command('0'),-1,len(command('0')) ) )



Window stuff

 

execute code all the time

In ThisWindow.TakeEvent PROCEDURE
put before EnhancedFocusManager.TakeEvent()

 

 

show tooltip for disabled fields - use a region with tip

tired of looking up code to see why a field isn't showing??? just disable and show a tool tip so the user can fix

with a disabled field you can't display a tool tip, so add a region around the fields, then add some code for the tooltip(b/c there isn't a tooltip option on the region properties)

 

- add a region around the disabled field(s)

  ****ensure the region is defined after the fields(in the actual window code)

- in the thiswindow.init section after self.open(windowname)

    ?region1{prop:tip} = 'If disabled, check this other field'

 

instead of hide(?fil:fieldname) , unhide(fil:fieldname)

use disable(?file:fieldname) , enable(?fil:fieldname)

 

other options are:

?fil:fieldname{prop:disable} = 0 (equals enable(?fil:fieldname) )

?fil:fieldname{prop:disable} = 1 (equals disable(?fil:fieldname) )

 

counting clock on window (to display when the window was refreshed)

  • put your variable on the window
  • on the window, do properties on Frame, goto Extra, then Timer (digits are in 100ths of a second, so 100 is 1 second) (this tells the window to retrieve the timer event every however many you set
  • in ThisWindow.Run procedure put LOC:WindowTime = clock()
  • in ThisWindow.TakeWindowEvent  , Event:Timer  put 
    • LOC:RefreshAge = clock() - LOC:WindowTime
      display

Cancel/Close a window - after prompt of "Changes will be lost" "Are your sure you want to Cancel" - do something if really canceling

***good for if there was an record added to another file that needs deleted

in ThisWindow.TakeCloseEvent PROCEDURE

after  ReturnValue = PARENT.TakeCloseEvent()

 

    IF ReturnValue = Level:Benign

      !the user answer "YES" to are you sure you want to cancel

        if self.request = insertrecord

           !do something

        end
    ELSE

      !the user answer "NO" or closed the prompt box

    END


Hide/Disable everything - remember to enable your buttons
 DISABLE(1,LASTFIELD())
 ENABLE(?OK)
 ENABLE(?Cancel) 

 

ignore an accept, (dont want to fire AN accept that is on a field)
      if not 0{Prop:AcceptAll}
 ...do your normal stuff
      end !end if not 0

 

ignoring an accept (dont want to fire NONE the accepts when the user hits save ???)
 put this as last embed of ACCEPT of your save button

 put your edits above the "Generated Code" of your save button
  !**** BEWARE - the code below will not fire accepts under input fields
  !----   make validation checks before
    0{prop:AcceptAll} = 0
    put(YOURFILENAME)
    post(event:closewindow,?ok)


disable the X on a window
-inside Global map:
 module('')
    GetSystemMenu(unsigned, signed),unsigned,PASCAL
    RemoveMenu(unsigned, signed, signed),signed,PASCAL
    DrawMenuBar(unsigned),signed,PASCAL
 end


-in your procedure, declare 3 varibles
hMenu                    UNSIGNED
nRemove                  SIGNED
nDraw                    SIGNED

-in your procedure, after OpenWindow (and after any kind of frame sets, mainly icon)
    hMenu   = GetSystemMenu(QuickWindow{Prop:Handle}, 0)
    nRemove = RemoveMenu(hMenu, 0F060h, 01000h)
    nDraw   = DrawMenuBar(QuickWindow{Prop:Handle})



capture closing with X or Escape or Closebutton (good for a lookup window and user getting out without selecting something)
ThisWindow.TakeWindowEvent PROCEDURE
... before generated code
    OF EVENT:CloseWindow
      ! Start of "Window Event Handling"
! [Priority 4999]
!here
    if not (self.response = RequestCompleted) !SAM 09/12/2014
        if loc:DebugIT then message('hello ... here in Window Events.CloseWindow ... NOT RequestCompleted ') .
        clear(CUS:CustomerNumber)
    end

    if (self.response = RequestCancelled) !SAM 09/12/2014
        if loc:DebugIT then message('hello ... here in Window Events.CloseWindow ... RequestCancelled').
        clear(CUS:CustomerNumber)
    end

 

capture closing with X or ALT-F4, but allowing Escape

 

 in ThisWindow.TakeCloseEvent PROCEDURE

 

!IF Event() = Event:CloseWindow AND Self.Response <> RequestCompleted !this wont allow any cancel

IF Event() = Event:CloseWindow AND Self.Response = 0

  message('Don''t close the window this way, it''s bad for your health.|' & 'Self.Response : ' & Self.Response,'Don''t exit this way',icon:exclamation )

  Return(Level:Notify)

END


 

in ThisWindow.Init PROCEDURE

 

0{prop:alrt,255} = EscKey

 

in ThisWindow.TakeEvent PROCEDURE

 

If Event() = Event:AlertKey and Keycode() = EscKey

!message('hello')

post(Event:accepted,?Cancel)

end

 

 

add CTL-ALT-F12 (hidden key stroke) to procedure

ThisWindow.init
    0{prop:alrt,255} = AltShiftF12
 

ThisWindow.TakeEvent
    If Event() = Event:AlertKey and Keycode() = AltShiftF12
        ?Group:TaxAndDeductions{prop:disable} = 0
        display(?Group:TaxAndDeductions)
        ?Group:HoursAndPay{prop:disable} = 0
        display(?Group:HoursAndPay)
    end


FDCB File Drop Control Box stuff

 

this is to set a combo (FDCB) based on another field being filed in
 also the FDCB is displaying a display value and the props itself

    FIL:field1 = DSP:field1
    get(FILENAME,FIL:Keybyfield1)

    Queue:FileDropCombo:2:FIL:field1    = FIL:Field1
    get(Queue:FileDropCombo:2,Queue:FileDropCombo:2:FIL:Field1)
    IF ~ERRORCODE() THEN
        ?dsp:field1{Prop:Selected} = POINTER(Queue:FileDropCombo:2)
    END
    dsp:field1 = Queue:FileDropCombo:2:FIL:Field1
    display(?dsp:field1)

 

FDCB drop box - clear it after selection
In your drops control "All Events"

    if keycode() = DeleteKey

        clear(PRE:FIELDNAME)
        ?PRE:FIELDNAME{PROP:Selected} = -1
        display(?PRE:FIELDNAME)

    end

 

After a FDCB selection, if there is something from the drop you need to investigate

for the accept in NewSelection embed

FDCBxx.TakeNewSelection()

 

FDCBxx = name of the class

 


BROWSE related stuff

 

 

display a browse filter on window
in the ThisWindow.TakeEvent Embed (PRIORITY=4000) simply code:

 dsp:Filter = BRW1::View:Browse{PROP:Filter}

 

reload a browse after file changes
    flush(BRW1.view)             
    BRW1.ResetQueue(Reset:Queue) ! Reset queue with current highlighted record retained.
    BRW1.PostNewSelection

 

disable right-mouse items

---disable delete options on browse(will disable buttons and right-mouse options)
-this disables the delete key and the right-mouse options(even if you have xplore template)

in BRWx.UpdateWindow before parent call

    SELF.DeleteControl = 0
    disable(?Delete)

-to disable others
    SELF.InsertControl = 0
    disable(?Insert)
    SELF.ChangeControl = 0
    disable(?Change)
    SELF.DeleteControl = 0
    disable(?Delete)

 

Set a browse to a certain record when opening

in ThisWindow.init right before the BRWx is initialized

  ! [Priority 8122]
    if prm:yourfield <> ''
 
            clear(PRE:Record)
            PRE:yourfield    = prm:yourfield
            LocateTo    = prm:yourfield
            display(?LocateTo)
 
    end !end if prm:yourfield <> ''

 

Locator string definition
!!> IDENT(4294966861),PICTURE(@s80)
[SCREENCONTROLS]
! PROMPT('Locate To:'),USE(?LocateTo:Prompt)
! STRING(@s20),USE(LocateTo),FONT(,,COLOR:Red,,CHARSET:ANSI)
[REPORTCONTROLS]
! STRING(@s20),USE(LocateTo)
LocateTo                 STRING(20)

 

 

Browse-NewSelection not getting updated variables if clicked with mouse
   in NewSelect embed include this before doing what you need to do
 BRWx.UpdateViewRecord()

 

set to first record in browse (good for if there are fields at top and setting after a search)
        Post(Event:ScrollTop,?Browse:1)
        select(?Browse:1)

 

set to browse box(if other fields are on window)
-also can use this to select a different field than the first one in the window based on some criteria

through embeds - "Window Events\Open Window" - select(?browse:1)

through source - search for "EVENT:OpenWindow" - select(?browse:1)

 

 

got a column in a list/browse box that is discolored and showing negative?
 look for a column defined TWICE in the list/browse box

color a field in a browse list box

  • properties of the procedure, extensions, colors - tells you how to do it
  • list box properties, hi-lite field you what colored, and check color
  • then back to the procedure extensions, color, your field should show up, put your condition and color in there

filter a record from loading into Browse

Goto:  Local Objects >> ABC Objects >> Browse on "File" (BrowseClass),ValidateRecord (AFTER Parent Call)

If ReturnValue = Record:OK
    If File:PartNo = HLD::PartNo
        ReturnValue = Record:Filtered
    End
End

HLD::PartNo = File:PartNo

set a variable based on browse loading
in BRWx.ResetFromView PROCEDURE
!beginning of code set your variable
    somerecordfound = 0

!in load of browse validate(BRWx.ValidateRecord PROCEDURE)

!at end of procedure set the screen var
    if somerecordfound
        ?String:MyWarning{prop:hide} = 0 
    else
        ?String:MyWarning{prop:hide} = 1
    end

set a variable during load of browse
BRWx.ValidateRecord PROCEDURE
!at end of code b/c let the browse filter take care of the not records
    If ReturnValue = Record:OK
        if somevariable
            somerecordfound = 1
        end
    End

 

get hi-lited record from browse queue

get(Queue:Browse,choice(?list))

look up non-related record embed point

BRWxx.SetQueueRecord()

refresh a browse - you figure out where you want to put it, like creating a refresh button on the window...

BRW1.ResetFromFile()
ThisWindow.Update

do something after delete message from a browse answered YES

Embeds->Local Objects->ABC objects->Browse on File->ResetFromAsk->Source:
if request = 3  and response = 1 then  ! if delete button and answer Yes
! updating parent
end


***IMPORTANT - if you need a piece of info from the record you are deleting, like to update another file
in procedure:   (or just embeds of button)
ThisWindow.TakeAccepted PROCEDURE
OF ?Delete
      get(Queue:Browse:YOURFILE,choice(?Browse:YOURFILE))
      HoldForDelete:PRE:FIELDNAME = queue:browse:YOURFILE.PRE:FIELDNAME

 

Search criteria on top of the browse box to build a filter

SetSearch   routine

!SER: fields are search fields on top of the browse that your allowing input

!Match Flag Values
!Match:Simple       EQUATE(0)
!Match:Wild         EQUATE(1)
!Match:Regular      EQUATE(2)
!Match:Soundex      EQUATE(3)
!Match:NoCase       EQUATE(10H)   ! May be added to Simple,Wild and Regular


    gotfilter# = 0
    clear(hld:filter)

!Example of doing match on a string field
    if ser:frame <> ''
        if gotfilter#
              hld:filter = clip(hld:filter) & ' and'
        end
        hld:filter = ' match(sm:frame,<39>' & ser:frame & '<39>,1)'
        gotfilter# = 1
    end

!EXAMPLE of doing a numeric field with not looking at the decimals
    if ser:hp1 > 0
        if gotfilter#
              hld:filter = clip(hld:filter) & ' and'
        end
        hld:filter = clip(hld:filter) & ' sm:hp1 >= ' & clip(format(ser:hp1,@n_10.2b)) & ' and sm:hp1 < ' & clip(format(int(ser:hp1+1),@n_10b))
        gotfilter# = 1
    end

!EXAMPLE of just a straight string
    if ser:LocationPrefix <> 'AL'
        if gotfilter#
              hld:filter = clip(hld:filter) & ' and'
        end
        hld:filter = clip(hld:filter) & ' inv:locationprefix = <39>' & clip(ser:LocationPrefix) & '<39>'
        gotfilter# = 1
    else
        gotfilter# = 1
    end



    if gotfilter#
        BRW1.SetFilter(hld:filter,2)
        dsp:Filter = BRW1::View:Browse{PROP:Filter}
        display(?dsp:filter)
        BRW1.ApplyFilter()
! stop('after-' & clip(BRW1::View:Browse{PROP:Filter}))
        BRW1.ResetQueue(Reset:Queue)
        BRW1.ResetFromView()
        ?Button:Search{prop:color} = color:none
        Post(Event:ScrollTop,?Browse:1)
        select(?Browse:1)
    end
      
 exit


EIP (Edit In Place) validate field
add field as "Column Specific" (in Configure Edit In Place)...this will create embed points for that field like:
EditInPlace::PRE:FIELDNAME.xxxxxx

 

 


This is tricky. Yes, the EIP control's TakeEvent is the proper method,
but you have to put it AFTER the PARENT call; you have to PRECEED it with
an "UPDATE(SELF.Feq)"; you DON'T use the Level:Benign/Notify/Fatal but
the EditAction: equates instead; and you DON'T update the file field, but
the BRW.Q field instead! For instance, from a test program, this checks
for and disallows a blank field. This is AFTER the PARENT call.


-in EditInPlace::PRE:FIELDNAME.TakeEvent

UPDATE(SELF.Feq)
IF ReturnValue AND ReturnValue <> EditAction:Cancel THEN
    IF BRW1.Q.File1:Field1 = '' THEN
        MESSAGE('Field Cannot Be Blank','Field Error',ICON:Exclamation)
        ReturnValue = EditAction:None
    END
END


-in BRWx::EIPManager.TakeFocusLoss PROCEDURE ...before the parent call
  this is so if the user keeps hitting the insert key or some other button

  if BRWx.Q.PRE:FIELDNAME = ''
    Self.Again = true
    Self.Column = BRWx.Q.PRE:FIELDNAME
    post(event:selected)
    return
  end


-on Insert Key embed put this to disable the escape key outside the browse
    alert(esckey)

 

EIP (Edit in Place) update another field on the file and in the list box

***the key here is to look at the fields declared in the list/browse and get their queue:browse name

EditInPlace::PRE:FIELD.TakeAccepted PROCEDURE(BYTE Action)

after  ReturnValue = PARENT.TakeAccepted(Action)

    queue:browse:1:PRE:OTHERFIELDTOBEUPDATED = queue:browse:1:PRE:FIELD * queue:browse:1:PRE:SOMEFIELD


EIP (Edit in Place) get Detailed Interface

goto Global Properties, Classes, Browser, Template Interface -  make it Detailed

 


Report stuff

 

 

Report straight to Printer based on variable...if not go straight to PDF
  *** if you have RPM Standard Report Template(mainly for fancy previewer and/or page renumbering) in the procedure, REMOVE it
        -if you need RPM page renumbering you can add a different RPM that
  *** if PDFx is in procedure, REMOVE it
  *** using the SV(Soft Velocity)/Clarion PDF template, you will have to open the generated PDF in the thiswindow.close procedure

 

-add Global template/extension "Report to PDF - Global"

-Procedure Properties - "Report Properties" button
  - Report Targets Tab, set "Report Target" to "Ask At Runtime"
     ***If this tab control does not appear after including the Advanced Report Generation Global , Extension, make sure to refresh the template generation sequence by selecting Source or Embeds in the proper procedure.

-in source, ThisWindow.init
  - put an erroneous if statement around "TargetSelector.AddItem(PDFReporter.IReportGenerator)" with the END after "SELF.AddItem(TargetSelector)"
    like so:
   if loc:ThisNeverGetsSet# = 1
   TargetSelector.AddItem(PDFReporter.IReportGenerator)
   IF NOT TargetSelector.ASK(1) THEN
      SELF.Kill()
      RETURN Level:Fatal
   END
   IF NOT TargetSelector.GetPrintSelected() THEN
      SELF.SetReportTarget(TargetSelector.GetSelected())
   END
   SELF.AddItem(TargetSelector)
   ! [Priority 8420]
   end
 
  - after that code put:
      IF loc:SendStraightToPrinter = 1
          !do nuttin, let it go straight to default printer
      else
          TargetSelector.AddItem(PDFReporter.IReportGenerator)
          SELF.SetReportTarget(PDFReporter.IReportGenerator)
          SELF.AddItem(TargetSelector)
      end

 

 

When using SVPDF - want to NOT pop the PDF(if exists previously from a PDF print) and they selected to go straight to printer

    in ThisWindow.init after the TargetSelector stuff  (this stuff is in C:\clarion6\LIBSRC\ABRPTGEN.INT and C:\clarion6\LIBSRC\ABPRPDF.CLW and C:\clarion6\LIBSRC\ABRPPSEL.CLW)

 

    loc:PDFSelected = 0
    IF ~SELF.ReportTarget &= NULL
        IF SELF.ReportTarget.WhoAmI() = RepGen:PDF
            loc:PDFSelected = 1
        end
    end

 

 

Change Jobname, either when goes to print queue OR goes to a pdf distiller with the filename
in ThisWindow.OpenReport PROCEDURE
        settarget(Report)
        0{prop:text} = 'Print of - ' & loc:YOURVARIABLEHERE 
        settarget()

exit report gracefully
in ThisWindow.init

before file opens(not tested after opens)
    if loc:QuitProcedure
        return Level:Fatal
    end

after file opens
    if loc:QuitProcedure
     SELF.Kill()
     RETURN Level:Fatal
    end

OR
   if loc:myscenarionotmet
     SELF.Kill()
     RETURN Level:Fatal
   end

 

print another line after normal detail lines are printed from main file

-in ThisWindow.endreport put your code

filter a record (without putting it in Report Properties Record Filter)

Embeds->Local Objects->ABC objects->Process Manager->ValidateRecord(AFTER Parent Call):

if PRE:FieldName <> Whatyouwant

    ReturnValue = Record:Filtered

end

 

Image aspect
DisplayImage  ROUTINE
  IF ?Image1{PROP:Height} > 100
    AspectRatio$ = ?Image1{PROP:Width}/?Image1{PROP:Height}
    ?Image1{PROP:Height} = 100
    ?Image1{PROP:Width} = 100 * AspectRatio$
  END
  IF ?Image1{PROP:Width} > 100
    AspectRatio$ = ?Image1{PROP:Height}/?Image1{PROP:Width}
    ?Image1{PROP:Width} = 100
    ?Image1{PROP:Height} = 100 * AspectRatio$
  END


change a field color before printing
    SETTARGET(Report)
    if loc:MyField <= 0
        ?loc:MyField{PROP:fontcolor} = color:red
    else
        ?loc:MyField{PROP:fontcolor} = color:none
    end
    SETTARGET
  PRINT(RPT:detail)

 

POP a calendar date selection in a Report before running

--data section add:
calendarX calendarclass

--in ThisWindow.init after the open files
Calendar1.SelectOnClose = True
Calendar1.Ask('Select a Date',loc:reportdate)

IF Calendar1.Response = RequestCompleted THEN
loc:reportdate = Calendar1.SelectedDate
else
ReturnValue = PARENT.EndReport()
End


***notes
Loc:reportdate is a local declared variable…use whatever you want
.ask first parameter is whatever you want the title of the window to be

display filter on report

in proc "ThisWindow.OpenReport PROCEDURE "

    loc:reportfilter = Process:View{PROP:FILTER}
!!!    message('here in the report:' & clip(loc:reportfilter) )

 


do totals on last page only in the footer
1. add a group break on a variable that wont really change
  ***ensure you leave the footer...you can delete the group header, then copy you detail line into the detail line the group break created(use the report code)
2. data - add a local var for a counter loc:recordcount
3. in code - after the print(detail), putin in loc:recordcount += 1
4. on report - add your string prompt on footer, and hide it
5. on report - add your local var (loc:recordcount) to the footer and hide it
6. in code add the following
ThisWindow.AskPreview PROCEDURE
!***before the parent call to PARENT.AskPreview
    report$?String:NumberofRecordsPrompt{prop:hide} = 0
    report$?loc:recordcount{prop:hide} = 0

 

 

Report to CSV with GWBCSV template

 

 http://comformark.com/pages/clarion-templates.php
   ***NOTE - you may want to increase filename, default is 100
            -in GWBCSV.Tpl find "GWBCSVFileName  CSTRING(100)"
            -remember not to go over 218 see "ShellExecute" section
           
1. add the GWBCSVExport to your Global Extensions
2. on the Report, open the progress window
 2.1 add the Control Template "PauseButton - Pause the Process"
     ***NOTE the GWBCSVReportExport will not show until you add the Pause
 2.2 add the GWBCSVReportExport to the window (this adds the export filename to the window)
 2.3 add a close to the file b/c sometimes it still has lock
     in ThisWindow.TakeCloseEvent put:
     close(GWBCSVFile)
3. in Source
 3.1. find in ThisWindow.init where the template sets the "GWBCSVFileName" and reset if need be
  ***NOTE the default is to create the file in the directory where the program is running
 3.2. if you want to open Excel(or whatever is associated with CSV)
  ***see "ShellExecute" for adding xxxxShellExecute/xxxxGetDesktopWindow procs
  
  in Data section put:
  OPN             CSTRING(10)
  NStr            CSTRING(5)
  ShowIT          SIGNED
  NoRecordsFound Byte  
  
  in ThisReport.Close put:
  if ~NoRecordsFound !make sure the report was produced before trying to open
      OPN       = 'OPEN'
      NSTR      = ''
      Showit    = 5
      HInst# = xxxxShellExecute(xxxxGetDeskTopWindow(),OPN,GWBCSVFileName,NStr,NStr,Showit)
      IF Hinst#>32
          !noerror
      ELSE
          MESSAGE('Shell launching error:' & hinst# & '|you may need to specify a file type in Win95|Go to Explorer; View; Options; File Types|and the specify a type for ' & GWBCSVFileName,' PT')
      END
  end !end ~NoRecordFound
  
  in ThisWindow.TakeNoRecords after parent call put:
      NoRecordsFound = 1

 

 

Report print jumbled either runs together or looks funky
The print can be straight to printer or produced to a PDF.

The Report doesn't have a "default" font to fall back to.

If the DPI is anything other than "Normal" then output of fonts looks funky

To Resolve in your Report:
Add FONT('Arial',10,,,) to the actual REPORT definition

Arial is installed as default on all systems.


To Resolve in Windows(without modifying Report)
Check the DPI settings in Windows

In Windows XP:
• Go to Start > Control Panel
• Double click Display
• Select the Settings Tab and click the Advanced button
• Change the drop-down menu under DPI setting to Normal size (96 DPI) and click OK
In Windows Vista:
• Go to Start > Control Panel
• Double click Personalization
• Click Adjust font size (DPI)
• Select Default scale (96 DPI) - fit more information and click OK
In Windows 7:
• Go to Start > Control Panel
• Click Display
• Select Smaller - 100%(default) and click Apply

 

 

Font problems with the PDF generation templates
taken from:
http://www.icetips.com/blog/index.php/2009/04/21/font-problems-with-the-pdf-generation-te

The problem stems from code in the ABPRPDF.CLW file where the width of the characters is calculated.
To fix this Arnor made some changes to the files.

This involves adding a single method to the PDFGeneratorClass class in ABPRPDF.INC and ABPRPDF.CLW:

Add to class declaration in ABPRPDF.INC (I put it in at the top of the
method list, around line 195):

AdjustDPIValues   PROCEDURE(Long pValue),Long
!! AB 2009-02-19  Adjusts DPI values


In the classfile, ABPRPDF.clw, I added this:

PDFGeneratorClass.AdjustDPIValues   PROCEDURE(Long pValue)!!,Long
!! AB 2009-02-19  Adjusts DPI values
HDcScreen  UNSIGNED
IDPI       Long
R          Real
L          Long
 Code
 R = 1
 HDcScreen = GetDC(0)
 If HDcScreen <> 0
   IDPI = GetDeviceCaps(HDcScreen, 88)
   L = ReleaseDC(0, HDcScreen)
   R = IDPI/96
 End
 Return (pValue / R)

 

In PDFGeneratorClass.AddFontDescriptor method, you have code like this:

!SET the fonts Width
LOOP LOC:I=SELF.FontsNames.FirstChar TO SELF.FontsNames.LastChar
   LOC:CharToTest=CHR(LOC:I)
   IF GetTextExtentPoint32(LOC:DC,LOC:CharToTest, 1,LOC:CharSize)<>0 THEN
      IF LOC:Subclasing THEN
         IF SELF.FontsNames.CharWidth[LOC:I] THEN
            SELF.FontsNames.CharWidth[LOC:I] = LOC:CharSize.eW
         END
      ELSE
         SELF.FontsNames.CharWidth[LOC:I] = LOC:CharSize.eW
      END
   END
END

 

I changed both of the assignments to the CharWidth to:

SELF.FontsNames.CharWidth[LOC:I] = |
           SELF.AdjustDPIValues(LOC:CharSize.eW)


In PDFGeneratorClass.GetTextWidth method, you have code like this:

 IF SelectObject(LOC:DC, LOC:HFont) THEN
    RV = GetTextExtentPoint32(LOC:DC,pText, LEN(pText),LOC:CharSize)
    LOC:OLDMAPMODE=SetMapMode(LOC:DC,LOC:OLDMAPMODE)
    DeleteObject(LOC:HFont)
    RETURN LOC:CharSize.eW + (LOC:CharSize.eW/20)
 END

 

I changed the RETURN to adjust the value:

RETURN SELF.AdjustDPIValues(LOC:CharSize.eW + (LOC:CharSize.eW/20))


This takes care of the font sizing problem in any DPI combination that I
threw at it:)

 


API stuff (External OS stuff)

Clarion Open Source (cant find how to prototype something?...look here
http://www.clarionopensource.com/


WINAPI - Windows information

 

-take the winapi app from the C:\clarion6\Examples\RESOURCE\Winapi  ***you will probably have to compile it
-run program and pick all the stuff you want (you might also include DWORD and HANDLE from the data structures part)
-it will generate a "winapi.clw" in whatever directory you put it in
-copy the "winapi.clw" whereever your clarion looks for clw's from (in you C6EE.red file)


in your app: goto "Global Properties", "Embeds"


Include the Equates section of WINAPI.CLW in the "After Global INCLUDEs" embed point:

   INCLUDE('WINAPI.CLW','Equates')


Include the Prototypes section of WINAPI.CLW in the "Inside the Global Map" embed point:

   INCLUDE('WINAPI.CLW','Prototypes')


most equates are here
C:\clarion6\LIBSRC\winequ.clw
C:\clarion6\LIBSRC\windows.inc


you could use OR use it for ideas
C:\clarion6\LIBSRC\hndutil.clw (contains the actual procedures)
 -these are everything it uses
 --C:\clarion6\LIBSRC\hndapi.inc (defines all the mapped procedures)
 --C:\clarion6\LIBSRC\hndequ.clw (all the equates)
 --C:\clarion6\LIBSRC\hndutil.inc (is a bunch of other utils)




ShellExecute
If you doing like so below, you can switch:
RUN('cmd /c "'&CLIP(CSVFileName)&'"')

Switch to below...(it wont spawn a dos window)


---PROTOTYPES--------------------------------
!make sure these are in your WINAPI.CLW (or put them in Global Embeds, "Inside Global Map")
!replace "xxxx" with your prefix, i would give it a prefix b/c one of your other templates might also use the shellexecutes
!*note - the 2nd 3rd 4th 5th variables must be CSTRINGS

    xxxxGetDeskTopWindow(),UNSIGNED,PASCAL,NAME('GetDeskTopWindow')

  OMIT('***Width16***',_WIDTH32_)
      xxxxShellExecute     (UNSIGNED,*CSTRING,*CSTRING,<*CSTRING>,<*CSTRING>,SIGNED),UNSIGNED,PASCAL,RAW,PROC,NAME('ShellExecute')
  !***Width16***
  COMPILE('***Width32***',_WIDTH32_)
      xxxxShellExecute     (UNSIGNED,*CSTRING,*CSTRING,*CSTRING,*CSTRING,SIGNED),UNSIGNED,PASCAL,RAW,PROC,NAME('ShellExecuteA')
  !***Width32***


---DATA-------------------------------------
! these must be defined, cant do inline b/c its expecting CSTRINGS
! did i mention your filename must be declared as CSTRING
! *note - if doing a CSV with Excel make filename 218 just to be safe...see http://www.xldatasoft.com/filename.htm

 

OPN       CSTRING(10)
NStr      CSTRING(5)
ShowIT    SIGNED

---Example CODE-------------------------------------
!the below is for to open google maps     

    fulladdress = 'http://maps.google.com/maps?hl=en&q=' & clip(CM:Address1) & ' ' & clip(CM:City) & ' ' & clip(CM:State) & ' ' & clip(CM:ZipCode)

    OPN       = 'OPEN'
    NSTR      = ''
    Showit    = 5
    HInst# = xxxxShellExecute(xxxxGetDeskTopWindow(),OPN,fulladdress,NStr,NStr,Showit)
    IF Hinst#>32
        !noerror
    ELSE
        MESSAGE('Shell launching error:' & hinst# & '|you may need to specify a file type in Win95|Go to Explorer; View; Options; File Types|and the specify a type for ' & clip(fulladdress),' PT')
    END


!this is for opening a CSV file with whatever app is associated with file extensions of CSV
!to test, just goto DOS prompt and type the filename...if it doesnt open the correct app, then fix with "SHFT-right mouse, open with"
   OPN       = 'OPEN'
   NSTR      = ''
   Showit    = 5
   HInst# = xxxxShellExecute(xxxxGetDeskTopWindow(),OPN,CSVFileName,NStr,NStr,Showit)
   IF Hinst#>32
      !noerror
   ELSE
      MESSAGE('Shell launching error:' & hinst# & '|you may need to specify a file type in Win95|Go to Explorer; View; Options; File Types|and the specify a type for ' & CSVFileName,' PT')
   END


 

Procedure to define 1 easy proc to do the file open so you dont have to define vars and such above 

PopFile              PROCEDURE  (string prm:filename)      ! Declare Procedure

loc:filename cstring(512)
OPN       CSTRING(10)
NStr      CSTRING(5)
ShowIT    SIGNED

  CODE
    loc:filename = prm:filename

    OPN       = 'OPEN'
    NSTR      = ''
    Showit    = 5
    HInst# = ShellExecuteDeclaredInWINAPI(PSDSGetDeskTopWindow(),OPN,loc:filename,NStr,NStr,Showit)
    IF Hinst#>32
        !noerror
    ELSE
        MESSAGE('Shell launching error:' & hinst# & '|you may need to specify a file type in Win95|Go to Explorer; View; Options; File Types|and the specify a type for ' & clip(loc:filename),' PT')
    END

 


From the Help File - things you can't never remember


Implicit variables (declare variables on the fly)
The Clarion language provides three types of implicit variables:
# A label terminated by a # names an implicit LONG.
$ A label terminated by a $ names an implicit REAL.
" A label terminated by a " names an implicit STRING(32).

 

Operating Assignments

Operating Assignment Functional Equivalent
 A += 1               A = A + 1
 A -= B               A = A - B
 A *= -5              A = A * -5
 A /= 100             A = A / 100
 A ^= I + 1           A = A ^ (I + 1)
 A %= 7               A = A % 7










 


Deep Assignment principle:(from newsgroup)
(1)  At least 1 VarName in the Target should exactly match that of the Source
(2)  Executing the deep assignment assigns the value from the Source for each matching VarName in the Target, ignoring those unmatched VarName
(3) Assigment syntax
 File to Queue -    ListQueue :=: RPH:Record
 Queue To File -    XYZ:Record :=: ListQueue
 File1 to File2 -   DEF:Record :=: OPQ:Record
 Queue1 to Queue2 - NameQue2 :=:  NameQue1


-Equates
InsertRecord  EQUATE (1)  !Add a record to table
ChangeRecord  EQUATE (2)  !Change the current record
DeleteRecord  EQUATE (3)  !Delete the current record

RequestCompleted  EQUATE (1)  !Update Completed
RequestCancelled  EQUATE (2)  !Update Aborted



BIND

bind('fieldname',fieldname)

 


NULL
if null(myfield) = 1     same as SQL: where myfield is null

so a compound check

if (myfield = '' or null(myfield) = 1 )

    message('My field can not be blank.')

    ?myfield{prop:background} = color:yellow

    select(?myfield)
    cycle

end

 

 

Data Types

Clarion C++ Modula-2
BYTE unsigned char BOOLEAN
BYTE unsigned char SHORTCARD
*BYTE unsigned char * var SHORTCARD
USHORT unsigned short CARDINAL
*USHORT unsigned short * var CARDINAL
SHORT short INTEGER
*SHORT short * var INTEGER
LONG long LONGINT
*LONG long * var LONGINT
ULONG unsigned long LONGCARD
*ULONG unsigned long * var LONGCARD
SREAL float REAL
*SREAL float * var REAL
REAL double LONGREAL
*REAL double * var LONGREAL
STRING can’t pass by value can’t pass by value
*STRING unsigned int, char * CARDINAL, ARRAY OF CHAR
*STRING(with RAW) char[] var ARRAY OF CHAR
*CSTRING(with RAW) char[] or char * var ARRAY OF CHAR
*PSTRING char[] or Char * ARRAY OF CHAR
GROUP struct var record type
*GROUP(with RAW) struct * var record type
*? void far* FarADDRESS
UNSIGNED unsigned int


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 


 

DATE/TIME stuff - date stuff is always a pain

 

  • Display day of week (modulus function)
    DATA 
    DisplayDayString STRING('Sunday   Monday   Tuesday  WednesdayThursday Friday   Saturday ')
    DisplayDayText   STRING(9),DIM(7),OVER(DisplayDayString)
    DayNumber short
    CODE
    AppFrame{Prop:StatusText,3} = CLIP(DisplayDayText[(TODAY()%7)+1])
    mystring = CLIP(DisplayDayText[(TODAY()%7)+1])
    DayNumber = (today()%7) + 1

  • 6 digit numeric to real date compare
    CSTS:CSDATE = format(CSH:MDATE,@D11)
    OR
    csts:csdate = format(today()-1,@d11)
  • date equivalents
    1900/01/01 = 36163
    1980/01/01 = 65382
    2008/01/01 = 75609
    2008/12/31 = 75974
  • Excel to Clarion and back
    Using Formulas for Dates or Times
    To use a LONG field containing a Clarion Standard Date or a Clarion Standard Time, you can create a formula in the product you are using to access the TopSpeed files.
    Here are some examples:
    • DATE
      • Converting a Clarion date to a Microsoft Excel Date: Subtract 36161 from the Clarion date value.
      • Converting a Microsoft Excel date to a Clarion Date: Add 36161 to the Microsoft Excel date value.
    • TIME
      • Converting a Clarion time to a Microsoft Excel time: Divide the Clarion time value by 86400 (the number of seconds in one day), then divide by 100 to express as a decimal value.
      • Converting a Microsoft Excel time to a Clarion time: Multiply the Microsoft Excel time value by 0.0000001157407407407410 (1 divided by the number of seconds in a day; includes the adjustment to convert back from a percentage).
      • Exporting excel time field - change to general(so its a number it will look like .270833333)
         (cast([EXCELDECIMALTIMETOSQL] as real)/0.0000001157407407407410) + 1
  • TIME - add XX minutes to clock or time field (XX is minutes you want to add/subtract)
    YOURFIELD = clock() + (XX * 6000)
    OR
    YOURNEWFIELD = TIMEFIELD + (XX * 6000)
  • MISC SQL and Clarion

    -Clarion long - SQL date time field to long Clarion
    These are all equal...
    select datediff( dd,'18001228',DateTimeFieldName )
    select datediff( dd,'18001228','20140717' )
    select datediff( dd,'1800-12-28','2014-07-17' )
    select datediff(dd,-36163,'2014-07-17' )

    -time field long(in sql), view in sql
    DateAdd(ms, ClarionTimeFieldasLong * 10, '1801-01-01')                         --whole date/time field set to 1801
    DateAdd(ms, ClarionTimeFieldasLong * 10, convert(varchar(10),getdate(),120)  ) --whole date/time field set to today
    DateAdd(ms, ClarionTimeFieldasLong * 10, 0)                                    --whole date/time zero SQL date part
    DateAdd(ms, ClarionTimeFieldasLong * 10, (ClarionDateFieldasLong -36163)  )    --whole date/time field using clarion long date and clarion long time
    convert(varchar(10),   DATEADD(second, FLOOR((ClarionTimeFieldasLong - 1) / 100), 0) , 108 )            --time part only HH:MM:SS (24hour clock)
    RTRIM( RIGHT( (CAST(DATEADD(second, FLOOR((ClarionTimeFieldasLong - 1) / 100), 0) AS CHAR(24))), 13 ) ) --time part AM/PM

    -Time SQL datetime to Long Clarion

    ISNULL((CAST(DATEDIFF(ss, CONVERT(DATETIME, CONVERT(VARCHAR(10), getdate(), 120) + ' 00:00:00.000'), getdate()) AS INT) * 100) + 1, 0)

 

SQL and Clarion

  • Clarion date to display as YYYYMMDD
    convert(datetime,([YOURCLARIONLONGDATEHERE]-36163)) AS whatevername
  • SQL DateTime (from DateTime field) to long - Clarion is 8,640,000 hundreths of a second in a day
    (datepart(hh,YOURDATE)*360000) + (datepart(n,YOURDATE)*6000) + (datepart(ss,YOURDATE)*100)
  • convert a concatenated fields that the date is stored in 4 spearate integer fields
    datediff(day, '18001228', convert(datetime, cast( cast((CCFIELD * 1000000 + YYFIELD * 10000 + MMFIELD * 100 + DDFIELD)as int(8)) as char(8) ) )  )
  • SQL datetime field to Clarion date
    datediff(day,'18001228',SQLDATETIMEFIELD)
  • SQL convert Clarion long date
    convert(datetime,([YOURCLARIONLONGDATEHERE]-36163)) AS whatevername
  • SQL to convert clarion date to just date part

    select convert(date,convert(datetime,([clariondatefield]-36163))),* from filename

  • SQL date time field to long Clarion (to get to the number)
    These are all equal...
    select datediff( dd,'18001228',DateTimeFieldName )
    select datediff( dd,'18001228','20140717' )
    select datediff( dd,'1800-12-28','2014-07-17' )
    select datediff(dd,-36163,'2014-07-17' )
  • Clarion long time field to SQL, view in sql
    DateAdd(ms, ClarionTimeFieldasLong * 10, '1801-01-01')                                   --whole date/time field set to 1801
    DateAdd(ms, ClarionTimeFieldasLong * 10, convert(varchar(10),getdate(),120)  ) --whole date/time field set to today
    DateAdd(ms, ClarionTimeFieldasLong * 10, 0)                                                   --whole date/time zero SQL date part
    DateAdd(ms, ClarionTimeFieldasLong * 10, (ClarionDateFieldasLong -36163)  )    --whole date/time field using clarion long date and clarion long time
    convert(varchar(10),   DATEADD(second, FLOOR((ClarionTimeFieldasLong - 1) / 100), 0) , 108 )            --time part only HH:MM:SS (24hour clock)
    RTRIM( RIGHT( (CAST(DATEADD(second, FLOOR((ClarionTimeFieldasLong - 1) / 100), 0) AS CHAR(24))), 13 ) ) --time part AM/PM

  • SQL clear the time part of a SQL defined DateTime
    dateAdd(dd,datediff(dd,0,YOURDATETIMEFIELD),0)
    ***if your convert datetime fields from a DB that uses both parts, Clarion doesnt like the time part of a DateTime field, so it needs zeroed
    ***if you have a date that is part of a Date group over and that is defined in a browse, you will probable get error "Fractional Truncation (01004)"
  • SQL function (scalar) to convert Clarion date to SQL datetime field
    ***this tip taken from news.softvelocity.com/s.c.thirdparty - Alan Telford
    ***also FM3 puts ds_ConvertClarionDateTime if you need to use it for some SQL code
    • create a function in your DB
      create  function dbo.YOURDATABASENAME cladate ( @InClaDate as int )
      returns datetime
      as
      begin
          declare @SqlDate int
          declare @SqlDateTime datetime
          declare @ClaRoot datetime
          declare @MssqlRoot datetime
          set @ClaRoot = 'Dec 28, 1800'
          set @MSSQLRoot = 'Jan 01, 1900'
          set @SqlDate = @InClaDate - datediff(day,@ClaRoot,@MssqlRoot)
          if @InClaDate > 2994626 -- invalid Clarion Date
            return 1
          if @InClaDate = 0
              return -1     -- zero date and time
          else
              set @SqlDateTime = convert(datetime,@SqlDate,0)
        return(@SqlDateTime)
      end
      

      see your function in SQL Manager - under "YOURDATABASENAME, Programmability, Functions, Scalar"
    • to call
      select cladate(YOURCLARIONDATE) as YOURDATE, *
      from YOURFILENAME
  • SQL function (scalar) to convert SQL date to Clarion int/long
    CREATE FUNCTION [dbo].[SQL2ClaDate] (@SQL_Date_Time DATETIME) 
    RETURNS INT AS 
    BEGIN
      RETURN ISNULL(CAST(DATEDIFF(d, '1800-12-28', @SQL_Date_Time) AS INT), 0)
    END
  • SQL function (scalar) to convert Clarion time(int/long) to SQL
    ---- to use: SQL time(24hour) dbo.clatime(myclariontimeinlong,0)
    ---- to use: clock with AM/PM dbo.clatime(myclariontimeinlong,1)
    CREATE FUNCTION dbo.ClaTime (@Cla_Time INT, @simpletime int = null) 
    RETURNS CHAR(12) AS 
    BEGIN
    declare @timechar char(12)
     if @simpletime = 1
      set @timechar =  convert(varchar(10),   DATEADD(second, FLOOR((@Cla_Time - 1) / 100), 0) , 108 )
     else
      set @timechar = RTRIM( RIGHT( (CAST(DATEADD(second, FLOOR((@Cla_Time - 1) / 100), 0) AS CHAR(24))), 13 ) )
     RETURN @timechar
    END
  • JDEdwards date CYYDDD(kinda julian format) to Clarion in SQL

    DATEDIFF(d, '1800-12-28', convert(char(10),dateadd(day,convert(int,right(@CYYDDD,3)),'01/01/'+left(right(@CYYDDD,5),2))-1,111) ) as dateClarion



Day of Week function

DayOfWeek     FUNCTION(xDate)
! Return short day of week name in xDate
!--------------------------------------------------------------------
  CODE
  RETURN CHOOSE(((xDate % 7) + 1),'Sunday','Monday','Tuesday','Wednesday',|
                                  'Thursday','Friday','Saturday')

 

 



 


You are here: Home-Computer Tips & Help-Programming-Clarion

Next Topic: SQL