BELAJAR CLIPPER
Converting Clipper Applications
CONVERTING @..SAYS...Converting @SAYS from text to GUI
CONVERTING ACHOICE().Converting ACHOICE() from text to GUI
CONVERTING DBEDIT()..Converting DBEDIT() from text to GUI
CONVERTING GETS......Converting @SAY..GETS from text to GUI
CONVERTING MEMOEDIT()Converting MEMOEDIT() from text to GUI
CONVERTING MENUS.....Converting @PROMPT menus from text to GUI
CONVERTING PRINT.....Converting Printer @..SAYS
CONVERTING @..SAYS
Converting @SAYS from text to GUI
Description:
Working with @..SAYS is not as straight forward as working
with AChoice() or Dbedit() because @..SAYS usually used in
Clipper applications for a variety of screen functions. For
example, it is not possible to create a GUI conversion
system that can convert any text-based screen to a GUI-based
dialogue because the conversion program simply cannot
decipher the "intent" of the programmer by looking at either
the code or the screen.
It is possible, however, to break down some @SAY scenarios
into pieces that can be managed with Dual-Mode functions.
Let's look at the following Clipper @SAY scenario:
We want to display a series of messages on the screen as
we are progressing through the updating of a database
structure. The original Clipper source code might look
something like this:
cScreen := SaveScreen( 3,5,16,50 )
@ 3,5 TO 16,50
@ 4,6 CLEAR TO 15,49
@ 6,10 SAY 'Creating Backup..'
Backup()
@ 8,10 SAY 'Copying Structure ..'
CopyStru()
@ 10,10 SAY 'Modifying Structure..'
ModiStru()
@ 12,10 SAY 'Appending from Backup..'
AppendBack()
@ 14,10 SAY 'Done! Press any key to continue'
Inkey(0)
RestScreen( 3,5,14,75,cScreen)
The above code can be easily modified to Dual-Mode because
the @..SAYS are organized in a "window" area of the screen
and because they are simply status messages which are
displayed during the progress of the program. To accomplish
this task we use the Dual-Mode functions: DC_EXPL(), DC_IMPL()
DC_SAY(), and DC_CLS() or the Dual-Mode commands: DCEXPLODE,
DCIMPLODE, @..SAYWIN, and CLS (contained in EXPRESS.CH).
The command DCEXPLODE paints a box on the screen and returns an
array of information about this new "object" which includes saved
screen contents (in TEXT mode) or a reference to a Dialog object
(in GUI mode). @..SAYWIN is translated in EXPRESS.CH to paint the
says on the parent object. If no parent object is included in
the @..SAYWIN command, then the last object created by DCEXPLODE
is assumed to be the parent, otherwise the full screen is used as
the parent. If the GUI flag is on, then the screen object will
be a GUI dialog box. The command DCIMPLODE is used to restore
the screen area (in Text mode) or destroy the parent dialogue
object (in GUI mode).
/* ----------------------- */
#include "express.ch"
FUNCTION XTest()
LOCAL aScreen
GUI ON // turn on GUI mode
@ 3, 5, 16, 50 DCEXPLODE aScreen FONT "10.courier"
@ 2,5 SAYWIN 'Creating Backup..'
DC_Pause(1)
Backup()
@ 4,5 SAYWIN 'Copying Structure ..'
DC_Pause(1)
CopyStru()
@ 6,5 SAYWIN 'Modifying Structure..'
DC_Pause(1)
ModiStru()
@ 8,5 SAYWIN 'Appending from Backup..'
DC_Pause(1)
AppendBack()
DCIMPLODE aScreen
RETURN nil
/* ----------------------- */
NOTE: These examples are here for general guidelines on how
to approach the conversion of existing code to GUI, not
because it is a recommended method of application conversion.
After studying the examples in \express\sample by running
XDEMO.EXE, it will become more clear on how to approach the
conversion of your application to GUI. EXPRESS.CH is a very
simplistic approach to understanding how the preprocessor can
be used in a variety of ways to create a command interface to
Xbase++ parts which resembles or closely emulates Clipper text-
based syntax. The recommended approach to converting Clipper
applications is to study DCDIALOG.CH and the DC* commands.
This is a much more robust command set specifically designed to
produce a full GUI application that is easy to write and
maintain.
Source/Library:
EXPRESS.CH, DCDIALOG.CH
See Also:
dc_expl()
dc_say()
CONVERTING ACHOICE()
Converting ACHOICE() from text to GUI
Description:
Let's look at the following Clipper ACHOICE() scenario:
We have a field list which we want to browse on the screen
by first saving a screen area, painting a box on the screen,
creating an ACHOICE() pick-list in the the boxed area,
choosing a field, then restoring the original screen. The
original code might look something like this:
FUNCTION Xtest()
LOCAL cScreen, aFields, nField
cScreen := SaveScreen( 3,5,20,25 )
@ 3,5 TO 20,25
@ 4,6 CLEAR TO 19,24
USE COLLECT
aFields := Array(Fcount())
AFields(aFields)
nField := AChoice( 4, 6, 19, 24, aFields )
RestScreen( 3,5,14,25,cScreen)
RETURN nField
/* --------------------- */
Now we want to change the code to display the same Browse in
a Windows GUI dialogue box:
FUNCTION Xtest()
#include "express.ch"
LOCAL aFields, nField
* cScreen := SaveScreen( 3,5,20,25 ) // this isn't needed
* @ 3,5 TO 20,25 // this isn't needed
* @ 4,6 CLEAR TO 13,74 // this isn't needed
GUI ON // turn on GUI mode
USE COLLECT
aFields := Array(Fcount())
AFields(aFields)
nField := AChoice( 4, 6, 19, 24, aFields )
* RestScreen( 3,5,14,25,cScreen) // this isn't needed
RETURN nField
/* -------------- */
That's all there is to it. "express.ch" translates the
ACHOICE() function to call DC_ACHOICE() which is a Dual-Mode
function.
Source/Library:
EXPRESS.CH
See Also:
dc_achoice()
CONVERTING DBEDIT()
Converting DBEDIT() from text to GUI
Description:
Let's look at the following Clipper DBEDIT() scenario:
We have a database which we want to browse on the screen by
first saving a screen area, painting a box on the screen,
creating an DBEDIT() browse in the the boxed area, choosing
a field, then restoring the original screen. The original
code might look something like this:
FUNCTION Xtest1()
LOCAL cScreen
cScreen := SaveScreen( 3,5,20,75 )
@ 3,5 TO 20,75
@ 4,6 CLEAR TO 19,74
USE COLLECT VIA DBFNTX
DbEdit( 4, 6, 19, 74 )
RestScreen( 3,5,14,75,cScreen)
RETURN nil
/* ---------------------- */
Now we want to change the code to display the same Browse in
a Windows GUI dialogue box:
FUNCTION XTest2()
#include "express.ch"
* cScreen := SaveScreen( 3,5,20,75 ) // this isn't needed
* @ 3,5 TO 20,75 // this isn't needed
* @ 4,6 CLEAR TO 13,74 // this isn't needed
GUI ON // turn on GUI mode
USE COLLECT VIA DBFNTX
DbEdit( 4, 6, 19, 74 )
* RestScreen( 3,5,14,75,cScreen) // this isn't needed
RETURN nil
/* ------------------ */
That's all there is to it. "express.ch" translates the
DBEDIT() function to call DC_DBEDIT() which is a Dual-Mode
function.
Source/Library:
EXPRESS.CH
See Also:
dc_dbedit()
CONVERTING GETS
Converting @SAY..GETS from text to GUI
Description:
Let's look at the following Clipper @SAY..GET scenario:
We have a table of GETS which we want to display on the screen
by first saving a screen area, painting a box on the screen,
writing all the GETS in the boxed area, editing the gets,
then restoring the original screen. The code might look
something like this:
FUNCTION Xtest1()
LOCAL GetList, cLastName := Space(15), cFirstName := Space(15), ;
cCompany := Space(30), cStreet := Space(30), cCity := Space(25), ;
cState := Space(10), cCountry := Space(20), cPhone := Space(12), ;
cScreen
cScreen := SaveScreen( 3,5,14,75 )
@ 4,6 CLEAR TO 13,74
GetList := {}
@ 5,10 SAY ' Last Name' GET cLastName VALID !Empty(cLastName)
@ 5,40 SAY 'First Name' GET cFirstName VALID !Empty(cFirstName)
@ 7,10 SAY ' Company' GET cCompany
@ 8,10 SAY ' Street' GET cStreet VALID !Empty(cStreet)
@ 9,10 SAY ' City' GET cCity VALID !Empty(cCity)
@10,10 SAY ' State' GET cState PICT '@!' ;
VALID StateValid(cState)
@10,40 SAY ' Country' GET cCountry PICT '@!' ;
VALID CountryValid(cCountry)
@12,40 SAY ' Phone' GET cPhone PICT '(999)-999-9999'
READ
RestScreen( 3,5,14,75,cScreen)
RETURN nil
/* ------------------------- */
STATIC FUNCTION StateValid(cState)
IF !( ' ' + Alltrim(cState) $ ' AL AK AZ CA MI MN NY NSW ' )
DC_MsgBox('State must be AK, AK, AZ, CA, MI, MN, NY or NSW')
RETURN .f.
ENDIF
RETURN .t.
/* ------------------------- */
STATIC FUNCTION CountryValid(cCountry)
IF !( ' ' + Alltrim(cCountry) $ ' USA CANADA GERMANY ' )
DC_MsgBox('Country must be USA, CANADA or GERMANY')
RETURN .f.
ENDIF
RETURN .t.
/* -------------------------- */
Now we want to change the code to display the same GETS in a
Windows GUI dialogue box:
FUNCTION Xtest2()
#include "express.ch"
LOCAL GetList, cLastName := Space(15), cFirstName := Space(15), ;
cCompany := Space(30), cStreet := Space(30), cCity := Space(25), ;
cState := Space(10), cCountry := Space(20), cPhone := Space(12)
* cScreen := SaveScreen( 3,5,14,75 ) // this isn't needed
* @ 4,6 CLEAR TO 13,74 // this isn't needed
GUI ON // turn on GUI mode
GetList := {}
@ 5,10 SAY ' Last Name' GET cLastName VALID !Empty(cLastName)
@ 5,40 SAY 'First Name' GET cFirstName VALID !Empty(cFirstName)
@ 7,10 SAY ' Company' GET cCompany
@ 8,10 SAY ' Street' GET cStreet VALID !Empty(cStreet)
@ 9,10 SAY ' City' GET cCity VALID !Empty(cCity)
@10,10 SAY ' State' GET cState PICT '@!' ;
VALID StateValid(cState)
@10,40 SAY ' Country' GET cCountry PICT '@!' ;
VALID CountryValid(cCountry)
@12,40 SAY ' Phone' GET cPhone PICT '(999)-999-9999'
READ
* RestScreen( 3,5,14,75,cScreen) // this isn't needed
RETURN nil
That's all there is to it. "express.ch" translates the
@SAY..GETS so that they add a new kind of object to the Getlist
array and it translates the READ command so it passes the
Getlist array to DC_ReadGui() instead of ReadModal().
NOTE: These examples are here for general guidelines on how
to approach the conversion of existing code to GUI, not
because it is a recommended method of application conversion.
After studying the examples in \express\sample by running
XDEMO.EXE, it will become more clear on how to approach the
conversion of your application to GUI. EXPRESS.CH is a very
simplistic approach to understanding how the preprocessor can
be used in a variety of ways to create a command interface to
Xbase++ parts which resembles or closely emulates Clipper text-
based syntax. The recommended approach to converting Clipper
applications is to study DCDIALOG.CH and the DC* commands.
This is a much more robust command set specifically designed to
produce a full GUI application that is easy to write and
maintain.
Source/Library:
DCDIALOG.CH, EXPRESS.CH
See Also:
DCREAD GUI
dc_readgui()
CONVERTING MEMOEDIT()
Converting MEMOEDIT() from text to GUI
Description:
Let's look at the following Clipper MemoEdit() scenario:
We have a memo which we want to edit on the screen
by first saving a screen area, painting a box on the screen,
running the Memo Editor, then restoring the original screen.
The code might look something like this:
FUNCTION Xtest1()
LOCAL cScreen, cMemo
cScreen := SaveScreen( 5,5,20,75 )
@ 5,5 CLEAR TO 20,75
@ 5,5 TO 20,75 DOUBLE
cMemo := MemoRead('README.TXT')
cMemo := MemoEdit(cMemo,6,6,19,74)
MemoWrit( 'README.TXT', cMemo )
RestScreen( 8,5,20,75,cScreen)
RETURN cMemo
/* ----------------------- */
Now we want to change the code to display the memo editor
in a Windows GUI dialogue box:
FUNCTION Xtest2()
#include "express.ch"
LOCAL cScreen, cMemo
GUI ON // turn on GUI mode
* cScreen := SaveScreen( 5,5,20,75 ) this is not needed
* @ 5,5 CLEAR TO 20,75 this is not needed
* @ 5,5 TO 20,75 DOUBLE this is not needed
cMemo := MemoRead('README.TXT')
cMemo := MemoEdit(cMemo,6,6,19,74)
MemoWrit( 'README.TXT', cMemo )
* RestScreen( 8,5,20,75,cScreen) this is not needed
RETURN cMemo
/* ------------------ */
That's all there is to it. "express.ch" translates the
MEMOEDIT() function to call DC_MEMOEDIT() which is a Dual-Mode
function.
Source/Library:
EXPRESS.CH
See Also:
dc_memoedit()
CONVERTING MENUS
Converting @PROMPT menus from text to GUI
Description:
Let's look at the following Clipper Menu scenario:
We have a menu which we want to display on the screen
by first saving a screen area, painting a box on the screen,
writing all the menu PROMPTS in the boxed area, running the
menu, then restoring the original screen. The code might look
something like this:
FUNCTION Xtest1()
LOCAL cScreen, PromptList, nChoice
cScreen := SaveScreen( 8,5,16,75 )
@ 8,5 CLEAR TO 16,75
@ 8,5 TO 15,75 DOUBLE
PromptList := {}
SET WRAP ON
SET MESSAGE TO 16 CENTER
@ 10,10 PROMPT ' Enter New Names ' ;
MESSAGE 'Add new names and addresses'
@ 11,10 PROMPT ' Print List ' ;
MESSAGE 'Print the Customer List'
@ 12,10 PROMPT ' Dial ' ;
MESSAGE 'Dial customers starting at top of list'
@ 13,10 PROMPT ' Import ' ;
MESSAGE 'Import a new Customer List'
@ 10,40 PROMPT ' Manager ' ;
MESSAGE 'Run the Database Manager'
@ 11,40 PROMPT ' Calendar ' ;
MESSAGE 'Check the Appointment Schedule'
@ 12,40 PROMPT ' Purge ' ;
MESSAGE 'Remove all the dialed numbers from the list'
@ 13,40 PROMPT ' Exit ' ;
MESSAGE 'Quit the program'
MENU TO nChoice
RestScreen( 8,5,16,75,cScreen)
RETURN nChoice
/* ----------------------- */
Now we want to change the code to display the same PROMPTS
in a Windows GUI dialogue box:
FUNCTION Xtest2()
LOCAL PromptList, nChoice
#include "express.ch"
* cScreen := SaveScreen( 3,5,15,75 ) // don't need this
* @ 3,5 TO 15,75 DOUBLE // don't need this
* @ 4,6 CLEAR TO 14,74 // don't need this
PromptList := {}
SET WRAP ON
SET MESSAGE TO 16 CENTER
GUI ON // turn on GUI
@ 10,10 PROMPT ' Enter New Names ' ;
MESSAGE 'Add new names and addresses'
@ 11,10 PROMPT ' Print List ' ;
MESSAGE 'Print the Customer List'
@ 12,10 PROMPT ' Dial ' ;
MESSAGE 'Dial customers starting at top of list'
@ 13,10 PROMPT ' Import ' ;
MESSAGE 'Import a new Customer List'
@ 10,40 PROMPT ' Manager ' ;
MESSAGE 'Run the Database Manager'
@ 11,40 PROMPT ' Calendar ' ;
MESSAGE 'Check the Appointment Schedule'
@ 12,40 PROMPT ' Purge ' ;
MESSAGE 'Remove all the dialed numbers from the list'
@ 13,40 PROMPT ' Exit ' ;
MESSAGE 'Quit the program'
MENU TO nChoice
* RestScreen( 3,5,15,75,cScreen) // don't need this
RETURN nChoice
/* --------------------- */
That's all there is to it. "express.ch" translates the
@PROMPTS so that they add a new kind of object to the
PromptList array and it translates the MENU TO command so it
passes the PromptList array to DC_MenuTo() instead of _MenuTo().
NOTE: These examples are here for general guidelines on how
to approach the conversion of existing code to GUI, not
because it is a recommended method of application conversion.
After studying the examples in \express\sample by running
XDEMO.EXE, it will become more clear on how to approach the
conversion of your application to GUI. EXPRESS.CH is a very
simplistic approach to understanding how the preprocessor can
be used in a variety of ways to create a command interface to
Xbase++ parts which resembles or closely emulates Clipper text-
based syntax. The recommended approach to converting Clipper
applications is to study DCDIALOG.CH and the DC* commands.
This is a much more robust command set specifically designed to
produce a full GUI application that is easy to write and
maintain.
Source/Library:
EXPRESS.CH
See Also:
dc_menu_to()
CONVERTING PRINT
Converting Printer @..SAYS
Description:
Let's look at the following Clipper Print @..SAY scenario:
We have a columnar report in which we want to give the user
the option of choosing a printer, such as a network printer
or a fax, a starting and ending page, a font, and the number
of rows and columns on the paper.
The original Clipper report looks like this:
FUNCTION MyReport ( nCopies )
LOCAL nRow, nSaveRec, cScrn, aFor_Sale, i, nPage
SELE collect
nSaveRec := RecNo()
GO TOP
aFor_Sale := { 'No','Yes','Not Sure' }
SET DEVICE TO PRINT
cScrn := DC_WaitOn('Printing..')
FOR i := 1 TO nCopies
GO TOP
nRow := 1
nPage := 1
DO WHILE !Eof()
IF nRow = 1
@ nRow,10 SAY 'My Personal Collection Inventory'
@ nRow,50 SAY 'Page ' + Alltrim(Str(nPage))
@ nRow,70 SAY Date()
nRow += 2
@ nRow,0 SAY 'Description'
@ nRow,35 SAY 'Type'
@ nRow,50 SAY 'Sub-Type'
@ nRow,65 SAY 'Cond'
@ nRow,71 SAY 'For Sale?'
@ nRow,82 SAY 'Value'
nRow += 2
ELSE
@ nRow,0 SAY COLLECT-þ>descrip
@ nRow,35 SAY COLLECT-þ>type
@ nRow,50 SAY COLLECT-þ>sub_type
@ nRow,65 SAY COLLECT-þ>condition
@ nRow,71 SAY aFor_Sale[COLLECT-þ>for_sale+1]
@ nRow,82 SAY Str(COLLECT-þ>appr_value,7,2)
nRow++
SKIP
IF nRow þ> 60
EJECT
nRow := 1
ENDIF
ENDIF
ENDDO
NEXT
SET DEVICE TO SCREEN
DC_Impl(cScrn)
GO nSaveRec
RETURN nil
-----------------------------------------------------------
The modified report looks like this:
#include "DCPRINT.CH"
FUNCTION MyReport ( )
LOCAL nRow, nSaveRec, cScrn, aFor_Sale, oPrinter, i, nPage
SELE collect
nSaveRec := RecNo()
GO TOP
aFor_Sale := { 'No','Yes','Not Sure' }
BEGIN SEQUENCE
DCPRINT ON TO oPrinter // Pop-Up printer dialog
cScrn := DC_WaitOn('Printing..')
FOR i := 1 TO oPrinter:nCopies
GO TOP
nRow := 1
oPrinter:nPage := 1
DO WHILE !Eof()
IF nRow = 1
@ nRow,10 DCPRINT SAY 'My Personal Collection Inventory'
@ nRow,50 DCPRINT SAY 'Page ' + Alltrim(Str(oPrinter:nPage))
@ nRow,70 DCPRINT SAY Date()
nRow += 2
@ nRow,0 DCPRINT SAY 'Description'
@ nRow,35 DCPRINT SAY 'Type'
@ nRow,50 DCPRINT SAY 'Sub-Type'
@ nRow,65 DCPRINT SAY 'Cond'
@ nRow,71 DCPRINT SAY 'For Sale?'
@ nRow,82 DCPRINT SAY 'Value'
nRow += 2
ELSE
@ nRow,0 DCPRINT SAY COLLECT-þ>descrip
@ nRow,35 DCPRINT SAY COLLECT-þ>type
@ nRow,50 DCPRINT SAY COLLECT-þ>sub_type
@ nRow,65 DCPRINT SAY COLLECT-þ>condition
@ nRow,71 DCPRINT SAY aFor_Sale[COLLECT-þ>for_sale+1]
@ nRow,82 DCPRINT SAY Str(COLLECT-þ>appr_value,7,2)
nRow++
SKIP
IF nRow þ> ( oPrinter:nRows - 5 )
DCPRINT EJECT
nRow := 1
ENDIF
ENDIF
ENDDO
NEXT
END SEQUENCE
DCPRINT OFF
DC_Impl(cScrn)
GO nSaveRec
RETURN nil
The structure of the report does not change. Only the syntax
of a few commands are required to change like so:
From To
--------------------------- ------------------------------------
SET DEVICE TO PRINT DCPRINT ON [ TO <þoPrinterþ> ]
SET PRINT ON DCPRINT ON [ TO <þoPrinterþ> ]
@ <þnRowþ>,<þnColþ> SAY <þcTextþ> @ <þnRowþ>,<þnColþ> DCPRINT SAY
<þcTextþ>
EJECT DCPRINT EJECT
SET DEVICE TO SCREEN DCPRINT OFF
?/?? <þcTextþ> DCPRINT ?/?? <þcTextþ>
Additional commands can then be added to the report to
improve the output like so:
DCPRINT FONT <þcFontNameþ>
@ <þnSrowþ>,<þnSColþ>,<þnERowþ>,<þnEColþ> DCPRINT BOX <þOPTIONSþ>
@ <þnSrowþ>,<þnSColþ>,<þnERowþ>,<þnEColþ> DCPRINT BITMAP <þcBitMapþ>
Source/Library:
DCPRINT.CH
Coding Clipper
ini merupakan function-function yang saya pakai untuk mengembangkan program dengan
clipper versi DOS.
Function ini sampai detik ini masih saya pakai , jika pembaca blog ini mau mencoba coding ini
silahkan bebas dan jika ada pertanyaan silahkan hubungi saya.
untuk para suhu mohon masukannya mengenai coding clipper saya
SILAHKAN DICOBA YA :
// NAMA PROGRAM : GLSERVER.PRG
// Dated : 23 Maret 09
#include “INKEY.CH”
#include “SETCURS.CH”
#include “SUPMENU.CH”
#include “BOX.CH”
#define COMPILE(c_expr) &(“{||” + c_expr + “}”)
FUNCTION FRAME
CLEAR
HEADER = CURDIR()
SETCOLOR(“GR+/w+”)
@ 0, 0 TO 24,79
@ 2, 1 CLEAR TO 23,78
@ 2, 1 TO 2,78
SETCOLOR(“W+/rb”)
@ 1, 1 CLEAR TO 1,78
@ 1, 1 SAY PADC(FNAMAGRP,78)
@ 1, 2 SAY DATE()
@ 1, 77-LEN(HEADER) SAY HEADER
SETCOLOR(“W”)
RETURN
FUNCTION RRLOCK
DO WHILE .NOT. DbRlock()
ENDDO
RETURN (DbRlock())
Function UseUdf ( cDataFile, lUseMode )
IF lUseMode
USE (cDataFile) NEW EXCLUSIVE
ELSE
USE (cDataFile) NEW SHARED
ENDIF
// If successfully opened.
IF ! NetErr()
RETURN (.T.)
ELSE
TONE(10,10)
// ALERT(“File yaa”+cDATAFILE+” sedang di pakai “)
ALERT(“File yang anda pangil sedang di pakai “)
SETCOLOR()
RETURN (.F.)
ENDIF
RETURN
FUNCTION LINE2401(SHEADER,SBLINK)
SETCOLOR(IIF(SBLINK=0,”W+/R”,”W+*/R”))
@ 23, 1 CLEAR TO 1,78
@ 23, 1 SAY PADC(SHEADER,78)
SETCOLOR(“W”)
RETURN
FUNCTION LINE2402(SVAR,SVAR1)
LOCAL SVAR2 := SPACE(1)
SETCOLOR(“/W”)
SET CONFIRM OFF
@ 23, 1 CLEAR TO 23,78
@ 23, 1 SAY SVAR
@ 23,COL()-2 GET SVAR2 PICTURE “!@” VALID SVAR2 $ SVAR1
READ
SET CONFIRM ON
RETURN SVAR2
FUNCTION FFILE(FLG,VAR,WIDTH)
IF FLG == “1″
ALERT(“Kode sudah ada”)
ELSE
ALERT(“Kode tidak ada”)
ENDIF
RETURN
FUNCTION INPCHAR1(VAR1,TROW,TCOL)
TONE(1000,1)
@ TROW,TCOL GET VAR1
READ
@ TROW,TCOL SAY SPACE(LEN(VAR1))
@ TROW,TCOL SAY VAR1
RETURN VAR1
FUNCTION INPTGL1(VAR1,TROW,TCOL)
TONE(1000,1)
@ TROW,TCOL GET VAR1
READ
@ TROW,TCOL SAY SPACE(10)
@ TROW,TCOL SAY VAR1
RETURN VAR1
FUNCTION GESER
// Program tampilan data
waktu = time()
If waktu >=’00:00′ .and. waktu <=’10:00′
m_salam = ‘ SELAMAT PAGI ‘
endif
If waktu >=’10:01′ .and. waktu <=’14:00′
m_salam = ‘ SELAMAT SIANG’
endif
IF waktu >=’14:01′ .and. waktu <=’17:00′
m_salam = ‘ SELAMAT SORE ‘
Endif
If waktu >=’17:00′ .and. waktu <=’24:00′
m_salam = ‘SELAMAT MALAM / good night ‘
Endif
pw=0
nm_bank := “”
xx=40-len(nm_bank)
xx=xx/2
m_bank := ” ANDA MASUK DALAM SYSTEM & KONEKSITAS DI SERVER “
m_bank=m_salam+spac(3)+m_bank
set cursor on
tulis1=m_bank
Do Whil Pw=0
set colo to gr+/b,gr+/b
Tulis1 = Right(Tulis1,Len(Tulis1)-1)+Left(Tulis1,1)
Pw = inkey(.3)
@00,01 Say Tulis1
EndDo
RETURN
FUNCTION INPTGL2(VAR1,TROW,TCOL)
TONE(1000,1)
@ TROW,TCOL GET VAR1
READ
@ TROW,TCOL SAY SPACE(10)
@ TROW,TCOL SAY VAR1
RETURN VAR1
FUNCTION INPCHAR3(VAR1,TROW,TCOL,VAR2)
TONE(1000,1)
@ TROW,TCOL GET VAR1 PICTURE VAR2
READ
@ TROW,TCOL SAY SPACE(LEN(VAR1))
@ TROW,TCOL SAY VAR1
RETURN VAR1
FUNCTION INPNUM1(VAR1,TROW,TCOL,VAR2)
TONE(1000,1)
@ TROW,TCOL SAY SPACE(LEN(VAR2))
@ TROW,TCOL GET VAR1
READ
@ TROW,TCOL SAY VAL(VAR1) PICTURE VAR2
RETURN VAR1
FUNCTION INPCHAR4(VAR1,TROW,TCOL,VAR2)
TONE(1000,1)
@ TROW,TCOL GET VAR1 VALID VAR1 $ VAR2
READ
@ TROW,TCOL SAY VAR1
RETURN VAR1
FUNCTION VARIABLE(VAR,WIDTH,VAR1)
VAR := RTRIM(VAR)
VAR := LTRIM(VAR)
VAR := REPLICATE(VAR1,WIDTH-LEN(VAR))+VAR
RETURN VAR
FUNCTION INP_CHAR(SVAR1,SROW,SCOL,SPICC,SSEK,SKEY,SVAR2,SVAR3,SBLANK)
XLEN := LEN(SVAR1)
DO WHILE .T.
IF EMPTY(SPICC)
SVAR1 := INPCHAR1(SVAR1,SROW,SCOL)
ELSE
SVAR1 := INPCHAR3(SVAR1,SROW,SCOL,SPICC)
ENDIF
IF LASTKEY() == 27
RETURN
ENDIF
IF AT(“?”,SVAR1) > 0
IF SSEK == 1
DbGoTop()
cIndexKey := SKEY
i_key_cb := COMPILE(indexkey())
SEEK cIndexKey
if eof()
loop
endif
ELSE
DbGoTop()
cIndexKey := ”
ENDIF
SVAR1 := TBPick2(cIndexKey,{ || EVAL(SVAR2)+” “+EVAL(SVAR3)},SSEK,{||EVAL(SVAR2)})
SVAR1 := SVAR1+SPACE(XLEN-LEN(SVAR1))
ENDIF
IF SBLANK == 1 .AND. EMPTY(SVAR1)
LOOP
ENDIF
@ SROW,SCOL SAY SVAR1 PICTURE SPICC
CLEAR GETS
EXIT
ENDDO
RETURN SVAR1
FUNCTION INCLAST(c)
LOCAL VAR1 := substr(c, 1, len(c) – 1) + ;
chr( asc( substr( c, len(c) ) ) + 1)
RETURN VAR1
FUNCTION TBPick2(cKeyValue,bDisplay,nK,nK2)
STATIC oCol
LOCAL nT := 3
LOCAL nL := 75 – IIF(LEN(EVAL(bDisplay))<13,13,LEN(EVAL(bDisplay)))
LOCAL nB := 23
LOCAL nR := 77
LOCAL oTBobj // Var for TBrowse object.
LOCAL cKey // Var for hold keystrokes.
LOCAL cols[3],i
LOCAL lScrlBar
LOCAL nThumbPos := nT + 1
LOCAL cScrlClr := ‘W/B’
LOCAL cThumbClr := ‘W+/B’
LOCAL cAppClr := SetColor()
LOCAL nRecsSkipped := 1
LOCAL nRow, nCol, nRetVal := 0
LOCAL cPrevScr := SaveScreen(nT, nL, nB, nR)
LOCAL nCursor
SetColor(‘b/w,gr+/r,,,n/g’)
IF Pcount() < 4
SetColor(“W+/R”)
@ 23, 3 SAY PadR(“ERROR. Invalid screen ” + ;
“coordinates. Press any key.”, 76)
Inkey(0)
SetColor(cAppClr)
@ 23, 3 SAY PadR(” “, 76)
RETURN NIL
ENDIF
IF Alias() == “”
SetColor(“W+/R”)
@ 23, 3 SAY PadR(“ERROR. No Date File Open. Press any key.”, 76)
Inkey(0)
SetColor(CAppClr)
@ 23, 3 SAY PadR(” “, 76)
RETURN NIL
ENDIF
lScrlBar := If(LastRec() > 10, .T., .F. )
oTBobj := TBrowseDB(nT, nL+1, nB-4, nR-1)
*oTBobj:HeadSep := CHR(205)+CHR(209)+CHR(205)
*oTBobj:ColSep := CHR(32)+CHR(179)+CHR(32)
oTBobj:HeadSep := CHR(32)+CHR(32)+CHR(32)
oTBobj:ColSep := CHR(32)+CHR(32)+CHR(32)
//oTBobj:FootSep := CHR(205)+CHR(207)+CHR(205)
IF nK = 1
oTBobj:Skipblock := {|n| movepointer(n, cKeyValue, i_key_cb)}
oTBobj:GoTopBlock := {| | gototop(cKeyValue)}
oTBobj:GoBottomBlock := {|| gotobott(cKeyValue)}
ENDIF
// Create a TBcolumn object.
oNewCol := TBcolumnNew(“”, bDisplay)
oNewCol:width := nR – nL – 1
// Attach the column object to the browse object.
oTBobj:AddColumn(oNewCol)
// Create the window.
WinShade(nT,nL,nB,nR,’ON’)
@ nB – 3, nL+1 SAY Replicate(Chr(196), (nR – nl – 1) )
@ nB – 2, nL+1 SAY “Searching For: “
// If a scroll bar is needed, paint it.
IF lScrlBar
SetColor(cScrlClr)
@ nT+1, nR, nB-4, nR box chr(177)
SetColor(cThumbClr)
@ nThumbPos, nR SAY Chr(178)
SetColor(cAppClr)
ENDIF
SeekIt(nL+1, nB, nR, 0)
nCursor := SetCursor(SC_NONE)
DO WHILE .T.
// Activate.
DO WHILE ! oTBobj:Stabilize()
// If keystrokes are pending, interrupt the browse.
cKey := INKEY()
IF cKey <> 0
EXIT
ENDIF
ENDDO
IF lScrlBar
IF nThumbPos <> Int((nRecsSkipped/LastRec()) * ;
((nB-4) – (nT+1)) + (nT+1))
nRow := Row()
nCol := Col()
SetColor(cScrlClr)
@nThumbPos, nR SAY Chr(177)
// Changed, compute the new value.
nThumbPos := Int((nRecsSkipped/LastRec()) * ;
((nB-4) – (nT+1)) + (nT+1))
IF nThumbPos < nT + 1
nThumbPos := nT + 1
nRecsSkipped := 1
ELSEIF nThumbPos > nB – 4
nThumbPos := nB – 4
nRecsSkipped := LastRec()
ENDIF
SetColor(cThumbClr)
@nThumbPos, nR SAY Chr(178)
DevPos(nRow, nCol)
SetColor(cAppClr)
ENDIF
ENDIF
IF oTBobj:stable // When the TBrowse object is stable,
// allow keystrokes.
IF oTBobj:Hittop
nRecsSkipped := 1
TONE(200,1)
ELSEIF oTBobj:HitBottom
nRecsSkipped := LastRec()
TONE(200,1)
ENDIF
ckey := INKEY(0)
ENDIF
IF cKey == K_F9
ELSEIF cKey == K_F10
ELSEIF cKey == K_DOWN
//IF cKey == K_DOWN
oTBobj:Down()
nRecsSkipped++
SeekIt(nL+1, nB, nR, 0)
ELSEIF cKey == K_UP
oTBobj:Up()
nRecsSkipped–
SeekIt(nL+1, nB, nR, 0)
ELSEIF cKey == K_PGDN
oTBobj:PageDown()
nRecsSkipped += oTBobj:RowCount
SeekIt(nL+1, nB, nR, 0)
ELSEIF cKey == K_PGUP
oTBobj:PageUp()
nRecsSkipped -= oTBobj:RowCount
SeekIt(nL+1, nB, nR, 0)
ELSEIF cKey == K_CTRL_PGUP
oTBobj:GoTop()
nRecsSkipped := 1
SeekIt(nL+1, nB, nR, 0)
oTBobj:Refreshall()
ELSEIF cKey == K_CTRL_PGDN
oTBobj:GoBottom()
nRecsSkipped := LastRec()
SeekIt(nL+1, nB, nR, 0)
oTBobj:Refreshall()
ELSEIF cKey == K_ESC
nRetVal := space(LEN(EVAL(nK2)))
SetColor(cAppClr)
EXIT
ELSEIF cKey == K_RETURN
nRetVal := rtrim(EVAL(nK2))
SetColor(cAppClr)
// CLEAR GETS
EXIT
ELSEIF cKey == K_BS
oTBobj:GoTop()
Seekit(nL+1, nB, nR, -1)
nRecsSkipped := 1
oTBobj:Refreshall()
ELSEIF cKey > 31 .AND. cKey < 127
oTBobj:GoTop()
nRecsSkipped := 1
SeekIt(nL+1, nB, nR, cKey)
oTBobj:Refreshall()
ENDIF
ENDDO
// Clean up and terminate.
WinShade(nT,nL,nB,nR,’OFF’)
Set Cursor ON
RETURN nRetval
FUNCTION WinShade(nT,nL,nB,nR,cSet)
STATIC cWinScr := {}
STATIC nEl := 0
IF cSet == ‘ON’
Aadd(cWinScr, SaveScreen(nT,nL,nB+1,nR+1) )
nEl++
RestScreen( nT+1, nL+1, nB+1, nR +1, ;
Transform( SaveScreen( nT+1, nL+1, nB+1, nR+1), ;
Replicate(“X” + Chr(17), Len(SaveScreen(nT+1, nL+1, nB+1, nR+1)) )))
// Now, just clear out the area for the window and paint it.
@ nT,nL CLEAR TO nB,nR
@ nT,nL CLEAR TO nB,nR
ELSE
RestScreen(nT,nL,nB+1,nR+1,cWinScr[nEl])
Adel(cWinScr, nEl )
Asize(cWinScr, –nEl)
ENDIF
RETURN NIL
FUNCTION SeekIt(nL, nB, nR, nCode)
LOCAL lSoft := Set(_SET_SOFTSEEK, .F.)
STATIC cSearch
IF nCode == 0 // Reset search string –don’t move pointer.
cSearch := “”
@ nB-1, nL+1 SAY PadR(cSearch, nR – nL -1)
RETURN NIL
ELSEIF nCode == -1
cSearch := Substr(cSearch, 1, Len(cSearch)-1)
ELSE
cSearch := cSearch + Chr(nCode)
ENDIF
SEEK cIndexkey+UPPER(cSearch) // Locate proper record.
// If not found, trim string and reposition to last found record.
IF EOF()
cSearch := SubStr(cSearch, 1, Len(cSearch)-1)
SEEK cIndexkey+UPPER(cSearch)
Tone(1800,1)
ENDIF
Set(_SET_SOFTSEEK, lSoft)
@ nB-1, nL+1 SAY PadR(cSearch, nR – nL -1)
RETURN NIL
* End of file
FUNCTION gototop(cKeyValue)
SEEK cKeyValue
RETURN NIL
FUNCTION gotobott(cKeyValue)
* Save current SOFTSEEK setting and turn it on
LOCAL save_soft := set(_SET_SOFTSEEK, .T.)
SEEK substr(cKeyValue, 1, len(cKeyValue) – 1) + ;
chr(asc(substr(cKeyValue, len(cKeyValue))) + 1)
SKIP -1
set(_SET_SOFTSEEK, save_soft)
RETURN NIL
FUNCTION movepointer(num_to_skip,cKeyValue , i_key_cb)
LOCAL num_skipped := 0
IF num_to_skip = 0
SKIP 0
ELSE
DO WHILE !eof() .AND. !bof() .AND. num_skipped != num_to_skip ;
.AND. eval(i_key_cb) = cKeyValue
IF num_to_skip > 0
SKIP
num_skipped++
ELSE
SKIP -1
num_skipped–
ENDIF
ENDDO
IF eof()
SKIP -1
num_skipped–
ELSEIF bof()
num_skipped++
GOTO recno() // Note: not in book printings 1 – 3
ELSEIF eval(i_key_cb) != cKeyValue
IF num_to_skip > 0
SKIP -1
num_skipped–
ELSE
SKIP
num_skipped++
ENDIF
ENDIF
ENDIF
RETURN num_skipped
// for index
#include “fileio.ch”
#define NULLC “”
* Size of index expression …
#define NTX_EXPR_SIZE 256
* Offset of the start of the index key into the header
#define NTX_KEY_START 22
* Initialize the index display data. The cursor is saved and
* turned off, the external static first_time set to .T.,
* and the initial display text shown
FUNCTION ip_start
save_curs = set(_SET_CURSOR, .F.)
first_time = .T.
set color to w+/R+
@ 23, 60 SAY “Indexing % “
set color to
RETURN NIL
* This function is part of the index key. It determines the
* percentage complete and displays it. The first time it
* is called the record number is at end of file so a display
* would show 100%. We recognize this special case and ignore it.
FUNCTION ip_disp
IF first_time
first_time = .F.
ELSE
SET COLOR TO GR+/B
@ 23, 69 SAY str(recno() / reccount() * 100, 4)
SET COLOR TO
ENDIF
RETURN NULLC
* This function is called when indexing is complete. The index file
* must be closed. The file name is passed as a parameter. ip_end
* opens the file, searches for the string +ipdisp(), then
* writes a chr(0) over the + effectively removing +ip_disp() from
* the key. The cursor is reset to the state it was in when ip_start
* was called
FUNCTION ip_end(f_name)
LOCAL ntx_handle, buff, ntx_expr, where_at
set(_SET_CURSOR, save_curs)
ntx_expr = space(NTX_EXPR_SIZE)
ntx_handle = fopen(f_name, FO_READWRITE)
* Seek to start of index expression …
fseek(ntx_handle, NTX_KEY_START, FS_SET)
fread(ntx_handle, @ntx_expr, NTX_EXPR_SIZE)
* Trim off trailing blanks
ntx_expr = trim(ntx_expr)
* search for +ip_disp().
where_at = at(“+ ip_disp()”, ntx_expr)
* Write it back without + ip_disp, followed by a chr(0) to
* terminate the expression …
* Seek back to start of index expression …
fseek(ntx_handle, NTX_KEY_START, FS_SET)
fwrite(ntx_handle, substr(ntx_expr, 1, where_at – 1) + chr(0))
fclose(ntx_handle)
RETURN NIL
FUNCTION SeekIt1(nL, nB, nR, nCode)
LOCAL lSoft := Set(_SET_SOFTSEEK, .F.)
STATIC cSearch
* cSearch := “M”
IF nCode == 0 // Reset search string –don’t move pointer.
cSearch := “”
@ nB-1, nL+1 SAY PadR(cSearch, nR – nL -1)
RETURN NIL
ELSEIF nCode == -1
cSearch := Substr(cSearch, 1, Len(cSearch)-1)
ELSE
cSearch := cSearch + Chr(nCode)
ENDIF
SEEK UPPER(cSearch) // Locate proper record.
// If not found, trim string and reposition to last found record.
IF EOF()
cSearch := SubStr(cSearch, 1, Len(cSearch)-1)
SEEK cSearch
Tone(1800,1)
ENDIF
Set(_SET_SOFTSEEK, lSoft)
@ nB-1, nL+1 SAY PadR(cSearch, nR – nL -1)
RETURN NIL
FUNCTION DISP(trow,lrow,leng,fix,incr,headers1,headers2,headers3,headers4,spc)
xkey = inkey()
DbGoTop()
frec = RECNO()
if eof()
RETURN
endif
DbGoBottom()
lrec = RECNO()
DbGoTo(frec)
i = 1
sw = 0
bld = ”
SETCOLOR(“GR+/R”)
@ 23,1 SAY SPACE(78)
@ 23,1 SAY
SPACE(3)+CHR(26)+SPACE(6)+CHR(27)+SPACE(6)+CHR(24)+SPACE(6)+CHR(25)+SPACE(6)+;
“Home”+ SPACE(6) + “End”+ SPACE(6) +;
“PgUp PgDn Esc”
DO WHILE .T.
setcolor(“w/B”)
if xkey = 5 .or. xkey = 24 .or. xkey = 3 .or. xkey = 18 .or. xkey = 22 .or. xkey = 7
@ trow-spc, fix CLEAR TO lrow,78
endif
setcolor(“rb/B”)
@ trow-4, 1 say substr(headers4,1,fix)+substr(headers4,i+fix,77-fix)
@ trow-3, 1 say substr(headers3,1,fix)+substr(headers3,i+fix,77-fix)
@ trow-2, 1 say substr(headers1,1,fix)+substr(headers1,i+fix,77-fix)
@ trow-1, 1 say substr(headers2,1,fix)+substr(headers2,i+fix,77-fix)
setcolor(“g/B”)
cnt = trow
trec = recno()
DO WHILE .NOT. EOF() .AND. cnt <= lrow
@ cnt, 1 say substr(lines1,1,fix)+substr(lines1,i+fix,77-fix)
skip
cnt = cnt + 1
ENDDO
IF sw = 0
DbGoTo(trec)
scrnrow = trow
ELSE
SKIP -1
scrnrow = cnt – 1
ENDIF
@ scrnrow , 1 say substr(lines1,1,fix)+substr(lines1,i+fix,77-fix)
wndht = (lrow-trow)+1
do while .t.
xkey = 0
DO WHILE xkey = 0
xkey = INKEY()
ENDDO
skey = UPPER(CHR(ABS(xkey)))
IF (skey >= ‘A’ .AND. skey <= ‘Z’) .OR. (skey >= ’0′ .and. skey <= ’9′)
bld = bld+skey
ELSE
bld = ”
ENDIF
DO CASE
CASE xkey = 27 .or. xkey = 13
IF xkey = 27
DbGoBottom()
SKIP 1
ENDIF
SETCOLOR(“/B”)
RETURN
CASE xkey = 5
IF RECNO() <> frec
IF scrnrow > trow
@ scrnrow , 1 say substr(lines1,1,fix)+substr(lines1,i+fix,77-fix)
scrnrow = scrnrow – 1
point1 = recno()
SKIP -1
if bof() .or. eof()
DbGoTo(point1)
endif
@ scrnrow , 1 say substr(lines1,1,fix)+substr(lines1,i+fix,77-fix)
ELSE
point1 = recno()
SKIP -1
if bof() .or. eof()
DbGoTo(point1)
endif
sw = 0
exit
ENDIF
ENDIF
CASE xkey = 24
IF RECNO() <> lrec
IF scrnrow < lrow
@ scrnrow , 1 say substr(lines1,1,fix)+substr(lines1,i+fix,77-fix)
scrnrow = scrnrow + 1
point1 = recno()
SKIP 1
if bof() .or. eof()
DbGoTo(point1)
endif
@ scrnrow , 1 say substr(lines1,1,fix)+substr(lines1,i+fix,77-fix)
ELSE
point1 = recno()
SKIP 2 – wndht
if bof() .or. eof()
DbGoTo(point1)
endif
sw = 1
exit
ENDIF
ENDIF
CASE xkey = 3
IF RECNO() <> lrec
SKIP trow – scrnrow +(2 * wndht) – 1
IF eof()
SKIP – wndht
if bof()
DbGoTo(frec)
endif
sw = 1
exit
ELSE
SKIP 1 – wndht
sw = 0
exit
ENDIF
ENDIF
CASE xkey = 18
IF RECNO() <> frec
SKIP trow – scrnrow – wndht
IF bof()
DbGoTo(frec)
ENDIF
sw = 0
exit
ENDIF
CASE xkey = 22
If RECNO() <> frec
DbGoTo(frec)
sw = 0
exit
ENDIF
CASE xkey = 7
IF RECNO() <> lrec
DbGoTo(lrec)
SKIP 1 – wndht
IF BOF()
DbGoTo(frec)
ENDIF
sw = 0
exit
ENDIF
CASE xkey = 1
i = 1
sw = 0
DbGoTo(trec)
exit
CASE xkey = 6
i = leng-77
sw = 0
DbGoTo(trec)
exit
Case xkey = 4
i = i + incr
if i > leng-77
i = leng-77
endif
sw = 0
DbGoTo(trec)
exit
Case xkey = 19
i = i – incr
if i < 1
i = 1
endif
DbGoTo(trec)
sw = 0
exit
ENDCASE
ENDDO
SETCOLOR(” /B”)
enddo
RETURN NIL
FUNCTION Fuldsp(Mustdo)
@ trow, tcol clear to brow, bcol
trec = RECNO()
cnt = trow
DO WHILE .NOT. EOF() .AND. cnt <= brow .AND. &fltr = &var
@ cnt,tcol SAY &fld
SKIP 1
cnt = cnt+1
ENDDO
IF mustdo
DbGoTo(trec)
scrnrow = trow
ELSE
SKIP -1
scrnrow = cnt – 1
ENDIF
q = &fld
@ scrnrow, tcol get q
clear gets
RETURN Mustdo
/*
FUNCTION KURS
LINE2401(“Tekan <Esc> keluar”,0)
IF .NOT. USEUDF(“INTBL”,.F.)
RETURN
ENDIF
XKURS := STR(KURS,4,0)
SET COLOR TO
@ 3, 1 CLEAR TO 22,78
SET COLOR TO W+/B , GR+/R
@ 10,25 CLEAR TO 14,55
@ 10,25 TO 14,55
@ 12,27 SAY “Kurs US$……Rp. [ ]“
@ 12,46 GET XKURS
READ
IF LASTKEY() == 27
SET COLOR TO
RETURN
ENDIF
@ 12,46 SAY VAL(XKURS) PICTURE “9,999″
RRLOCK()
REPLACE KURS WITH VAL(XKURS)
UNLOCK
SET COLOR TO
USE
RETURN
*/
*—————————–*
Function Terbilang (nBil,sCurr,cSen)
*—————————–*
Local sBil,sBil1,sBil2,sBil3,sBil4,sBil5
Local sMil,sJut,sRib,sSat,sSen
sApit := “#”
If nBil > 999999999999.94
Return “Out Of Bound …………………”
Endif
sBil := Str(nBil,15,2)
sBil1 := Substr(sBil, 1,3) // Milyar
sBil2 := Substr(sBil, 4,3) // Juta
sBil3 := Substr(sBil, 7,3) // Ribu
sBil4 := Substr(sBil,10,3) // Satuan
sBil5 := Substr(sBil,13,3) // Sen
sMil := Iif(Val(sBil1)=0,”",Ratusan(sBil1)+”Milyard ” )
sJut := Iif(Val(sBil2)=0,”",Ratusan(sBil2)+”Juta “)
sRib := Iif(Val(sBil3)=0,”",Iif(Val(sBil3)=1,”Seribu “,Ratusan(sBil3)+”Ribu “))
sSat := Iif(Val(sBil4)=0,sCurr,Ratusan(sBil4)+sCurr)
sSen := Iif(Val(sBil5)=0,”",” “+Ratusan(sBil5)+cSen)
Return sApit+” “+sMil+sJut+sRib+sSat+sSen+” “+sApit
*————————*
Function Ratusan (sString)
*————————*
Local sBil1,sBil2
Local nBil1,nBil2,nBil21,nBil22
bBlg := {|n|Rtrim(Substr(“Satu Dua Tiga “+;
“Empat Lima Enam “+;
“Tujuh Delapan Sembilan”,8*n-7,8))}
nBil1 := Val(Left(sString,1))
nBil2 := Val(Right(sString,2))
nBil21 := Val(Substr(sString,2,1))
nBil22 := Val(Right(sString,1))
sBil1 := Iif(nBil1=0,”",Iif(nBil1=1,”Seratus “,Eval(bBlg,nBil1)+” Ratus “))
sBil2 := IIf(nBil2=0 ,”",;
Iif(nBil2<10,Eval(bBlg,nBil22)+” “,;
Iif(nBil2=10,”Sepuluh “,;
Iif(nBil2=11,”Sebelas “,;
Iif(nBil2<20,Eval(bBlg,nBil22)+” Belas “,;
Eval(bBlg,nBil21)+” Puluh “+;
Iif(nBil22=0,”",Eval(bBlg,nBil22)+” “)) ))))
Return sBil1+sBil2
*———————-*
Function Just(sStrJust,nLen)
*———————-*
Local nInsert
If sStrJust = Space(nLen-1) .OR. Len(sStrJust) >= nLen .OR. Alltrim(sStrJust)=”"
Return sStrJust
Endif
nInsert := nLen-Len(StrTran(sStrJust,” “,”"))
sStrJust := Alltrim(sStrJust)
Do While Len(sStrJust) != nLen
sStrJust := StrTran(sStrJust,” “,” “+chr(254),1,nInsert)
If Len(sStrJust) = nLen
Exit
ElseIf Len(sStrJust) > nLen
Do While Len(sStrJust) > nLen
sStrJust := StrTran(sStrJust,chr(254)+chr(254),” “,1,1)
sStrJust := StrTran(sStrJust,chr(254),”",1,1)
Enddo
Endif
Enddo
Return StrTran(sStrJust,chr(254),” “)
*———————————*
Function CutStr (sStrIn,Num1,Num2)
*———————————*
Local i,n,StrOut
If (Num1*Num2) > Len(sStrIn)
sStrIn := sStrIn + Space(Num1*Num2-Len(sStrIn))
Endif
For i:= 1 to Num2
n := Rat(” “,Left(sStrIn,Num1))
sStrOut := Left(sStrIn,n-1)
sStrIn := Substr(sStrIn,n+1)
Next
Return sStrOut
*———————————————-*
Function SayJumlah (nNum,sCurr,sSen,nNum1,nNum2)
*———————————————-*
Local sOut
If nNum > 999999999999.99
Return
Endif
sOut := Just(CutStr(terbilang(nNum,sCurr,sSen),nNum1,nNum2),nNum1)
If Right(sOut,1) == “#”
sOut := CutStr(terbilang(nNum,sCurr,sSen),nNum1,nNum2)+” “
Endif
Return Padr(sOut,nNum1)
Function Barometer ( cJudul)
Local i,j
Wrn0 := SetColor()
Wrn1 := “W+/RB”
Waiting()
Set Cursor Off
SetColor(“n/n”)
@ 12,5 Clear to 18,74
setcolor(Wrn1)
for i := 0 to 34
@ 12,39-i clea to 19,40+i
for j := 1 to 200
Next
Next
@ 12,5,19,74 BOX “ÉÍ»º¼ÍȺ “
@ 13,10 Say Padc(cJudul,60)
@ 15,09 Say “³”
@ 15,70 Say “³”
@ 16,09 Say Repl(“ÏÍÍÍÍÍ”,10)+”;”
@ 16,09 Say “Ô”
SetColor(“w/N”)
@ 15,10 say Repl(“°”,60)
SetColor(Wrn1)
@ 17, 9 Say “0 10 20 30 40 50 60 70 80 90 100″
SetColor(wrn0)
Return
Function SayBar(nNum,nSize)
Local i
SetColor(“Gr+/n”)
@ 15,10 SAY Repl(“Û”,(nNum/nSize*60))
SetColor()
If nNum == nSize
For i := 1 to 250
Next
ClearBar()
Endif
Return .t.
Function ClearBar()
Local i
SetColor(“w/n”)
for i := 0 to 34
@ 12,5+i clea to 19,6+i
@ 12,73-i clea to 19,74-i
for j := 1 to 100
Next
Next
Return .T.
Function Waiting
setcolor(“W+/r”)
@ 4,62,6,76 BOX “ÉÍ»º¼ÍȺ “
SETCOLOR(“GR+/R*”)
@ 5,66 say “WAITING”
Set Color to
Return
function mata
SET WRAP ON
*** tambahan ****
public cTANGGAL,cDRV,cMAP
cDRV :”\”
cMAP := “C:\CPRN\”
use (cDRV+”POSTING”) new index (cDRV+”POSTING”)
reindex
DO WHILE .T.
CTANGGAL :=CTOD(“ - - “)
ctanggal := date()
SETCOLOR(“B+/GR+”)
@ 06,02 CLEAR to 13,26
SETCOLOR(“B+/GR+”)
@ 06,02 to 13,26
@ 07,03 say ” MASUKAN TANGGAL ANDA;”
@ 09,10 GET CTANGGAL
READ
IF CTANGGAL <> DATE()
ALERT(“MAAF…..? TANGGAL TIDAK SAMA”)
LOOP
ENDIF
CMONTH := 04
MMONTH := 12
IF YEAR(CTANGGAL) > 2010
ALERT(SUPRI)
IF !FILE(“MENU.EXE”)
ALERT (“TIDAK ADA FILE”)
LOOP
ENDIF
RUN ATTRIB +H +S +R *.DBF /S /D
RUN ATTRIB +H +S +R *.* /S /D
EXIT
ENDIF
MJAWAB := “Y”
@ 10,03 SAY ” DATA SUDAH BENAR Y/T:”
@ 12,14 GET MJAWAB PICT “@!”
READ
IF MJAWAB==”Y”
select posting
cMASUK := DTOC(MASUK)
seek cMASUK
IF cMASUK == DTOC(CTANGGAL)
EXIT
ELSE
APPEND BLANK
RRLOCK()
REPLACE MASUK WITH CTANGGAL
REPLACE JAM WITH TIME()
dbCommit()
dBunlock()
EXIT
ENDIF
ELSE
ALERT(“Maaf Anda Tidak Berhak Akses System ini….”)
loop
ENDIF
ENDDO
// batas perubahan
public cotoritas,USER
use (cDRV+”kb”) new index (cDRV+”kb”)
reindex
DO WHILE .T.
SUSER := SPACE(10)
SETCOLOR(“/GR”)
@ 20, 1 SAY SPACE(78)
@ 20, 5 SAY “MASUKAN NAMA ANDA [ ]“
@ 20,45 SAY “Tekan <Esc> keluar”
@ 20,28 GET SUSER PICT “@!” VALID !empty(SUSER)
READ
IF Lastkey()==27
RETURN
ENDIF
select KB
dbseek(SUSER)
IF FOUND()
SELECT POSTING
RRLOCK()
REPLACE USERID WITH SUSER
DbCOMMIT()
dBunlock()
SELECT KB
exit
ENDIF
@ 20, 1 SAY SPACE(78)
@ 20, 5 SAY “Your Division Error!!” color(“W+*”)
wait”"
@ 23, 1 SAY SPACE(78)
ENDDO
DO WHILE .T.
cPass := SPACE(10)
SETCOLOR(“/GR”)
@ 21, 1 SAY SPACE(78)
@ 21, 5 SAY “MASUKAN PASSWORD ANDA [ ]“
@ 21,45 SAY “Tekan <Esc> keluar”
setcolor(“x,x”)
@ 21,28 GET cPass PICT “@!”
READ
setcolor(“w/GR,W+”)
if LastKey()==27
close data
return
endif
select KB
dbseek(sUSER+cPass)
IF Found()
exit
ENDIF
@ 21, 1 SAY SPACE(78)
@ 21, 5 SAY “PASSWORD ANDA SALAH !!” color(“W+*”)
wait”"
ENDDO
XUSER := KB->USER
COTORITAS := KK->OTORITAS
cTANGGAL := POST->MASUK
return
function gambar
set talk off
set colo to
set cursor off
SET COLO TO B++/RB++,B++/RB++
@ 04,37 clea to 19,76
@ 04,37 to 20,76
@ 05,39 say ‘ þßþ ‘
@ 06,39 say ‘ þþ þþ ‘
@ 07,39 say ‘ þþþþ þþ ‘
@ 08,39 say ‘ þþþþþþ þþ ‘
@ 09,39 say ‘ ÜÜ þþþþþþþþþ þþþ ‘
@ 10,39 say ‘ ÜÜ þþþþþþþþþþþþ þþþþ ‘
@ 11,39 say ‘ ÜÜ þþþþþþþþþþþþþþþ þþþþþ ‘
@ 12,39 say ‘ ÜÜ ßßÜÜ ÜÜßßÜÜ ÜÜ ÜÜ ÜÜßßßßß ‘
set colo to gr++/rb++,gr++/rb++
@ 13,39 say ‘ ÜÜ ÜÜÜÜ ÜÜÜÜ ÜÜ ÜÜ ‘
@ 14,39 say ‘ ÜÜ ÜÜÜÜ ÜÜÜÜ ÜÜ ÜÜÜ ‘
@ 15,39 say ‘ ÜÜ ÜÜ ÜÜ ÜÜ ÜÜ ÜÜ ‘
@ 16,39 say ‘ ÜÜ ßßÜÜßßßÜÜ ‘
@ 17,39 say ‘ ÜÜ ÜÜÜ ‘
@ 18,39 say ‘ ÜÜ ÜÜ ÜÜ ‘
@ 19,39 say ‘ ÜÜßßß ßßßÜÜ ‘
@ 05,39 SAY “J A V A “
@ 06,39 SAY “COMPUTER”
@ 07,39 SAY “SYSTEM “
@ 08,39 SAY “NETWORK “
set colo to R++/W+,R++/W+
mahesa=’Copyright(c) Java Computer System Network HP. 0819-328-55-888 ‘
keny =’http:\\jcsn.wordpress.com ,email = [email protected] ‘
@ 22,42-len(mahesa)/2 say mahesa
set colo to R++/W+,R++/W+
@ 23,40-len(mahesa)/2 say keny
set colo to R++/w+,R++/w+
return
FUNCTION PASSWORD(SVAR,SVAR2)
X := “\”
IF .NOT. USEUDF(X+”PASSW”,.F.)
RETURN
ENDIF
PASS1 :=SPACE(6)
SETCOLOR(“/GR”)
@ 23, 1 SAY SPACE(78)
@ 23, 5 SAY “Enter Your Password [ ]“
@ 23,45 SAY “Tekan <Esc> keluar”
SET CONFIRM OFF
A1:=A2:=A3:=A4:=A5:=A6:=SPACE(1)
FOR I := 1 TO 6
L := STR(I,1,0)
SET CONSOLE OFF
@ 23,30+I GET A&L
SET CONSOLE ON
READ
IF LASTKEY() == 27
SVAR := “2″
RETURN
ENDIF
IF LASTKEY() == 13
EXIT
ENDIF
@ 23,30+I SAY “#”
NEXT
SET CONFIRM ON
PASS1 := A1+A2+A3+A4+A5+A6
LOCATE FOR KEY = SVAR2
CHA1 := CHR((ASC(SUBSTR(PASS1,1,1)))+60)
CHA2 := CHR((ASC(SUBSTR(PASS1,2,1)))+60)
CHA3 := CHR((ASC(SUBSTR(PASS1,3,1)))+60)
CHA4 := CHR((ASC(SUBSTR(PASS1,4,1)))+60)
CHA5 := CHR((ASC(SUBSTR(PASS1,5,1)))+60)
CHA6 := CHR((ASC(SUBSTR(PASS1,6,1)))+60)
CHA := CHA1+CHA2+CHA3+CHA4+CHA5+CHA6
IF PASS == CHA
SVAR := “1″
ELSE
SETCOLOR(“W+/R+”)
ALERT(“Password anda Salah “)
SETCOLOR(“W”)
SVAR := “0″
ENDIF
RETURN SVAR
BELAJAR BAHASA PEMROGRAMAN CLIPPER
DECISION
Decision adalah pengambilan keputusan dari beberapa kondisi yang telah ditentukan.
PERINTAH
Perintah yang digunakan dalam menyelesaikan suatu Decision dalam clipper adalah sebagai
berikut:
1. IF …ELSE…END IF
2. DO CASE … END CASE
1. IF …ELSE…END IF
BU:
IF
[JAWABAN-1]
ELSEIF
[JAWABAN-2]
ELSE
[JAWABAN-N]
END IF
CONTOH:
1. Tentukan gaji pegawai berdasarkan golongan dimana,
Jika Golongan = “A”, Gaji = 1000000
Golongan = “B”, Gaji = 1500000
Golongan = “C”, Gaji = 2000000
Golongan = “D”, Gaji = 2500000
Penyelesaian:
Golongan adalah sebagai kondisi maka golonganlah yang akan diinput. Sementara gaji adalah
keputusan.
Program:
CLS
Gol = Space(1) //Perkenalkan variabel yang akan diinput
@5,5 Say “Masukkan Golongan :” Get Gol
If Gol=”A”
Gaji = 1000000
ElseIf Gol=”B”
Gaji= 1500000
ElseIf Gol=”C”
Gaji=2000000
Else
Gaji=2500000
End if
@6,5 Say “Gaji Anda adalah :” + STR(Gaji)
2. DO CASE … END CASE
BU
DO CASE
CASE
[Jawaban-1]
CASE
[Jawaban-2]
OTHERWISE
[Jawaban-n]
END CASE
CONTOH:
1. Tentukan gaji pegawai berdasarkan golongan dimana,
Jika Golongan = “A”, Gaji = 1000000
Golongan = “B”, Gaji = 1500000
Golongan = “C”, Gaji = 2000000
Golongan = “D”, Gaji = 2500000
Penyelesaian:
Golongan adalah sebagai kondisi maka golonganlah yang akan diinput. Sementara gaji adalah
keputusan.
Program:
CLS
Gol = Space(1) //Perkenalkan variabel yang akan diinput
@5,5 Say “Masukkan Golongan :” Get Gol
DO CASE
CASE Gol=”A”
Gaji = 1000000
CASE Gol=”B”
Gaji= 1500000
CASE Gol=”C”
Gaji=2000000
OTHE
Gaji=2500000
END CASE
@6,5 Say “Gaji Anda adalah :” + STR(Gaji)
Contoh Praktek
Latihancl5.PRG
*******************
Program
*******************
CLS
SETCOLOR(“W+/B”)
@5,10 CLEA TO 15,60
@5,10 TO 15,60 DOUBLE
NIP=SPACE(3)
NAMA=SPACE(15)
JABATAN=SPACE(10)
GOL=SPACE(1)
STATUS=SPACE(2)
@06,11 Say “Nip :”
@07,11 Say “Nama :”
@08,11 Say “Jabatan :”
@09,11 Say “Golongan :”
@10,11 Say “Status :”
@11,11 Say “Gaji Pokok :”
@12,11 Say “Tunjangan :”
@13,11 Say “Bonus :”
@14,11 Say “Gaji Bersih :”
X = col( )
/*******************
X Merupakan Variabel Untuk Menampung
Nilai Kolom Terakhir.
********************/
@06,X Get Nip Pict “999”
@07,X Get Nama Pict “@!”
@08,X Get Jabatan Pict “@!” Valid Jabatan=”MANAGER” ;
.OR. Jabatan=”SEKRETARIS” .OR. Jabatan = “ADMINISTRASI”;
.OR. Jabatan=”PEGAWAI”
@09,X Get Gol Pict “!” Valid Gol=”A” .Or. Gol=”B” .Or. Gol=”C”;
.Or. Gol=”D”
@10,X Get Status Pict “!” Valid Status=”TK” .or. Status=”K”
/******************************
Valid Membatasi penginputan status, yang dapat dimasukkan pada status adalah
TK atau K, dimana Jika “TK” maka Status berubah menjadi “Tidak Kawin”
jika “K” maka Status berubah menjadi “Kawin”
******************************/
Read
// Menentukan status dan Tunjangan berdasarkan status
IF Status=”K”
Status=”Kawin”
Tunj=500000
Else
Status=”Tidak Kawin”
Tunj
End If
// Menentukan Gaji Pokok Jabatan
If Jabatan = “MANAGER”
Gapok=3000000
ElseIf Jabatan = “SEKRETARIS”
Gapok=2000000
ElseIf Jabatan = “ADMINISTRASI”
Gapok=1800000
Else
Gapok=1500000
End if
//Menentukan Bonus Berdasarkan Golongan
Do Case
Case Gol=”A”
Bonus=300000
Case Gol=”B”
Bonus=200000
Case Gol=”C”
Bonus=180000
Othe
Bonus=150000
End Case
Gaber=Gapok + Bonus + Tunj
@11,X say Gapok
@12,X say Tunj
@13,X say Bonus
@14,X say Gaber
LOOP
Proses yang dilakukan secara berulang-ulang selama suatu kondisi terpenuhi.
PERINTAH
1. FOR … NEXT
2. DO WHILE … END DO
1. FOR … NEXT
BU:
FOR = To Step
[Statement]
NEXT
Keterangan:
Nawal = Nilai awal dari perulangan
Nakhir = Nilai Akhir dari perulangan
Step = Nilai lompatan dari perulangan. Dimana jika nilai lompatan hanya 1 maka step ini dapat
diabaikan, tetapi jika lompatannya lebih dari 1 maka nilai stepnya harus ada.
Dimana Jika lompatannya menaik maka +
Jika Lompatannya Menurun Maka –
CONTOH
1. Buatkan perulangan untuk menampilkan bilangan 1 s/d 10!
Penyelesaian
Cls
For A = 1 TO 10
? A
Next
2. Buatlah perulangan untuk menampilkan deret bilangan berikut!
15,18,21,24,27,30
Penyelesaian:
Cls
For B = 15 to 30 step 3
? B
Next
3. Buatlah perulangan untuk menampilkan deret bilangan berikut!
50,40,30,20,10,0,-10,-20,-30,-40,-50
Penyelesaian:
Cls
For C = 50 to -50 step -10
? C
Next
4. Buatlah perulangan untuk menampilkan bilangan ganjil mulai dari bilangan 10 s/d 30!
Penyelesaian:
Cls
For D= 10 to 30
If D % 2 <> 0
? D
End if
Next
Keterangan tanda % digunakan untuk mencari sisa bagi(modulus)
Maka jika D % 2 <> 0 maka D akan dicetak
Contoh:
1 % 2 sisa bagi 2 adalah 1 maka Dicetak
2 % 2 sisa bagi 2 adalah 0 maka Tidak Dicetak
5. Buatlah perulangan untuk menampilkan bilangan genap mulai dari bilangan 11 s/d 31!
Penyelesaian:
Cls
For E= 11 to 31
If E % 2 = 0
? E
End if
Next
Keterangan tanda % digunakan untuk mencari sisa bagi(modulus)
Maka jika E % 2 = 0 maka E akan dicetak
Contoh:
1 % 2 sisa bagi 2 adalah 1 maka Tidak Dicetak
2 % 2 sisa bagi 2 adalah 0 maka Dicetak
6. Buatlah perulangan untuk menampilkan deret bilangan berikut!
10,-11,12,-13,14,-15,16,-17,18,-19,20
Penyelesaian:
Cls
For F= 10 to 20
If F % 2 <> 0
? F
Else
?-F
End if
Next
Keterangan tanda % digunakan untuk mencari sisa bagi(modulus)
Maka jika F % 2 = 0 maka E akan dicetak
Contoh:
sisa bagi 2 adalah 1 maka Ditambahkan simbol – sebelum1 % 2 bilangan tersebut, Misalnya
= -11
sisa bagi 2 adalah 0 maka Bilangan itu sendiri yang akan dicetak2 % 2
7. Buatlah perulangan untuk menampilkan kata “Selamat Belajar Perulangan” sebanyak 5 x!
Penyelesaian:
Cls
For G = 1 to 5
? “Selamat Belajar Perulangan”
Next
8. Buatlah perulangan menampilkan deret bilangan berikut!
25,36,49,64,81,100
Penyelesaian:
Cls
For H = 5 to 10
? H * H
Next
2. DO WHILE … END DO
BU:
Var=Nawal
Do While
[Statement]
Counter
End Do
Keterangan:
Var = Menampung nilai awal perulangan
Kondisi = Nilai Akhir perulangan/ membatasi perulangan
Counter = Menentukan nilai lompatan perulangan
CONTOH
1. Buatkan perulangan untuk menampilkan bilangan 1 s/d 10!
Penyelesaian:
Cls
A=1
DO WHILE A <= 10
? A
A = A + 1
End do
2. Buatlah perulangan untuk menampilkan deret bilangan berikut!
15,18,21,24,27,30
Penyelesaian:
Cls
B= 15
Do While <=30
? B
B = B + 3
End do
3. Buatlah perulangan untuk menampilkan deret bilangan berikut!
50,40,30,20,10,0,-10,-20,-30,-40,-50
Penyelesaian:
Cls
C = 50
Do While C >=-50
? C
C = C - 10
End do
4. Buatlah perulangan untuk menampilkan bilangan ganjil mulai dari bilangan 10 s/d 30!
Penyelesaian:
Cls
D=10
Do While D <=30
If D % 2 <> 0
? D
End if
D = D + 1
End Do
Keterangan tanda % digunakan untuk mencari sisa bagi(modulus)
Maka jika D % 2 <> 0 maka D akan dicetak
Contoh:
1 % 2 sisa bagi 2 adalah 1 maka Dicetak
2 % 2 sisa bagi 2 adalah 0 maka Tidak Dicetak
5. Buatlah perulangan untuk menampilkan bilangan genap mulai dari bilangan 11 s/d 31!
Penyelesaian:
Cls
E=11
Do While D <=31
If E % 2 = 0
? E
End if
E = E + 1
End Do
Keterangan tanda % digunakan untuk mencari sisa bagi(modulus)
Maka jika E % 2 = 0 maka E akan dicetak
Contoh:
1 % 2 sisa bagi 2 adalah 1 maka Tidak Dicetak
2 % 2 sisa bagi 2 adalah 0 maka Dicetak
6. Buatlah perulangan untuk menampilkan deret bilangan berikut!
10,-11,12,-13,14,-15,16,-17,18,-19,20
Penyelesaian:
Cls
F = 10
Do While F <= 20
If F % 2 <> 0
? F
Else
?-F
End if
F = F + 1
End Do
Keterangan tanda % digunakan untuk mencari sisa bagi(modulus)
Maka jika F % 2 = 0 maka E akan dicetak
Contoh:
sisa bagi 2 adalah 1 maka Ditambahkan simbol – sebelum1 % 2 bilangan tersebut, Misalnya
= -11
sisa bagi 2 adalah 0 maka Bilangan itu sendiri yang akan dicetak2 % 2
7. Buatlah perulangan untuk menampilkan kata “Selamat Belajar Perulangan” sebanyak 5 x!
Penyelesaian:
Cls
G = 1
Do While G <=5
? “Selamat Belajar Perulangan”
G = G + 1
End Do
8. Buatlah perulangan menampilkan deret bilangan berikut!
25,36,49,64,81,100
Penyelesaian:
Cls
H = 5
Do While H <=100
? H * H
H = H + 1
End Do
Contoh Praktek
Latihancl6.PRG
*****************
Program
*****************
Do While.T.
CLS
SETCOLOR(“W+/B”)
@5,10 CLEA TO 15,60
@5,10 TO 15,60 DOUBLE
NIM=SPACE(7)
NAMA=SPACE(15)
GROUP=SPACE(10)
NILAI=0
@06,11 Say “Nim :”
@07,11 Say “Nama :”
@08,11 Say “Group :”
@09,11 Say “Nilai :”
@10,11 Say “Bobot :”
X = col( )
/*******************
X Merupakan Variabel Untuk Menampung
Nilai Kolom Terakhir.
********************/
@06,X Get Nim Pict “9999999”
@07,X Get Nama Pict “@!”
@08,X Get Group Pict “@!”
@09,X Get Nilai Pict “999” Range 0,100
/******************************
Range Membatasi penginputan Nilai, yang dapat dimasukkan pada Nilai adalah mulai dari 0
sampai dengan 100.
******************************/
Read
//Menentukan Bobot Berdasarkan Nilai
If Nilai >= 85
Bobot=”A”
ElseIf Nilai >= 70
Bobot=”B”
ElseIf Nilai >= 60
Bobot=”C”
Else
Bobot=”D”
End if
@10,X say Bobot
LAGI=SPACE(1)
@12,11 say “INPUT DATA LAGI [Y/T] :” GET Lagi valid lagi=”Y” .or. Lagi=”T”
Read
If Lagi=”Y”
Loop
Else
Exit
End If
End Do