2012年11月26日 星期一

VFP 筆記 Visual FoxPro

資料來源:  朱孝國的筆記本

簡介

  • 早期開發資料庫系統的開發工具:dBase=>Clipper。
  • 微軟公司買下Foxbase之後,在Windows上改名為 Foxprow=>Visual Foxpro。
  • 上述開發工具都可存取副檔名為DBF的資料庫格式,我們通稱為xBase。
  • 開發軟體核心就能處理資料庫的不多,現存的僅存VFP,Delphi等。
  • 大多數的開發軟體核心都不具有資料庫處理能力(VB,Java,C++.....),而是透過ODBC或JDBC這種開放架構來存取。
  • VFP的Rushmore技術使得搜尋效率在filebase資料庫中穩站第一名。
  • 因為xBase這種存取關連式資料庫的開發工具在早期十分流行,因此許多學校到目前還使用VFP
  • VFP加入了現代物件導向的特點後,加上微軟持續發展,目前最新的版本為9.0

VFP基本語法 vs. VFP的SQL語法

操作VFP基本語法VFP的SQL語法
瀏覽資料庫use emp
browse
select * from emp
設定條件瀏覽資料庫use emp
browse for salary>50000
select * from emp where salary>50000
建立資料庫create empCREATE TABLE emp (id c(6))
修改紀錄use emp
replace salary with 60000 for name="Peter"
update emp set salary=60000 where name="Peter"
新增紀錄use emp
append blank
replace name with "Tom"
INSERT INTO emp (name) values ("Tom")
刪除紀錄use emp
delete for name="Tom"
delete from emp where name="Tom"

OLE/COM/ActiveX的使用

  • 拜物件導向技術發展之功,微軟創造了COM的環境,讓我們可以使用不同的程式來使用相同COM元件(*.dll,*.ocx),節省了許多的時間,但其實VFP對於這些COM control的相容性並沒有VB,VC等那麼好,並不是所有的control都能拿到VFP中用喔。
  • 透過選單中tools/object browser開啟其Com Libraries便可掃瞄登錄檔中所有已註冊的com元件,並檢視其屬性,方法與事件等,取得如何使用的資訊。

COM元件的註冊

就微軟的DCOM技術而言,可供重複使用的control必須先在 Windows 中註冊才能使用,註冊control一般來說有5種方法,它們有各自的優點,運用範圍也不同。

使用安裝程式註冊

  • 利用VFP本身的InstallShield製作安裝程式,安裝時可將系統所需要的control註冊,反安裝時亦可將control解除註冊。
  • 此方法最適合給使用者使用。

使用regsvr32.exe註冊

利用微軟系統提供的regsvr32.exe可註冊指定的元件,若成功註冊,會跳出一視窗「DllRegisterServer in xxx.ocx succeeded」,若解除成功則會跳出「UnDllRegisterServer ...........」代表成功的執行了元件內部的註冊函數DllRegisterServer或解註冊函數UnDllRegisterServer。
  • 於命令提示字元手動執行
    • 註冊control:regsvr32 \windows\system\netshare.ocx      &&需注意control的路徑
    • 解除control:regsvr32 /u \windows\system\netshare.ocx
  • 透過自訂函數執行
    • 撰寫自訂函數MyRegsvr
    • Function MyRegsvr ( lpcRegFilename, lplIsreg )
         If File(lpcRegFilename)
               lpcRegFilename = iif(llisreg, lpcRegFilename, [ /u ] + lpcRegFilename)
               Run /n regsvr32 &&lpcRegFilename
         Endif
         Return
      Endfunc
    • 註冊control:MyRegsvr( "netshare.ocx", .T.)      &&需注意control的路徑
    • 解除control:MyRegsvr( "netshare.ocx", .F.)

使用VFP註冊

  • 進入VFP後,透過選單中tools/options/controls/ActiveX controls,可看見所有已註冊的 control,可透過右側的Add...來增加想要註冊的control
  • 此方法只能用在系統開發者,因為使用者並沒有VFP的主程式。

使用元件本身的註冊函數

  • 註冊control
    declare integer DllRegisterServer IN myserver.dll
    ?DllRegisterServer()
  • 解除control
    declare integer DllUnregisterServer IN myserver.dll
    ?DllUnregisterServer()
  • 若撰寫成函數,範例如下
    Function MyDllRegister ( lpLibFileName, isReg)
      isReg = iif(type("isReg")="U", .T., isReg)
      lpProcName = iif(isReg, "DllRegisterServer", "DllUnregisterServer" )
      Declare INTEGER (lpProcName) in (lpLibFileName)
      return &&lpProcName.()  &&傳回0表示成功
    Endfunc
    MyDllRegister( "netshare.ocx", .T.) &&若為解除註冊則為 MyDllRegister( "netshare.ocx", .F.) 
    Clear Dlls

VFP連接Sql Server的範例

*********************
* SQL Server 連結設定
*********************
lcUserName="sa"
lcServerName="127.0.0.1"
lcUserPass="123456"
lcDBName="master"
ConnectionHandle=SQLSTRINGCONNECT([DRIVER=SQL Server;SERVER=]+lcServerName+[;DATABASE=]+lcDBName+[;UID=]+lcUserName+[;PWD=]+lcUserPass )
if ConnectionHandle <= 0
    messagebox('無法連接至 SQL SERVER ('+ lcServerName +')',16,"SQL Connect Error" )
    quit
endif
*********************
* 執行 SQL
*********************
SQLCOMMAND="select a.uname, a.upass, a.udep ,s.address ;
from admin a, schools s where a.uname=s.scode and s.scode = '034729'"
mret=sqlexec(ConnectionHandle,SQLCOMMAND)
if mret<=0
    messagebox('sql敘述執行失敗' )
    quit
endif
*********************
* 取回後處理
*********************
copy to tmp\tmp.dbf
browse
*********************
* 離線與關閉
*********************
mret=SQLDISCONN(ConnectionHandle)
if mret<=0
    messagebox('離線失敗' )
    quit
endif

VFP讀寫與開啟excel的範例

開啟Excel 檔的範例

Exl_file = GETFILE('XLS', '選擇或取消', '選擇', 0, '請選擇要開啟的Excel檔')
DO CASE
CASE EMPTY(Exl_file)
Messagebox("並未選擇要開啟的Excel檔",1+32,"訊息視窗")
QUIT
OTHERWISE
? "你選擇要開啟的Excel檔是 "+Exl_file
ENDCASE
oExl=CREATEOBJECT("Excel.application")
if VARTYPE(oExl) <> "O"
= MESSAGEBOX("EXCEL沒有安裝或損壞或因為記憶體不足而無法使用!",64,"提示")
return
endif
oExl.SheetsInNewWorkbook?=1
oExl.Visible=.T.
oExl.workbooks.Open('&Exl_file')
oExl.activesheet.rows(1).insert
oExl.activecell.formular1c1 = "表頭"
with oExl.SELECTION.font
.name = "細明體"
.fontstyle = "normal"
.size = 20
.strikethrough = .f.
.superscript = .f.
.subscript = .f.
.outlinefont = .f.
.shadow = .f.
endwith

讀入Excel 檔的範例

Exl_file = GETFILE('XLS', '選擇或取消', '選擇', 0, '請選擇要讀入的Excel檔')
DO CASE
CASE EMPTY(Exl_file)
Messagebox("並未選擇要讀入的Excel檔",1+32,"訊息視窗")
QUIT
OTHERWISE
? "你選擇要讀入的Excel檔是 "+Exl_file
ENDCASE
import from &Exl_file Type xl8
browse

寫出為Excel檔的範例(含欄位名稱)

use Student
copy to stu_info type XL5

寫出為CSV 檔的範例(含欄位名稱)

use Student
copy to stu_info type CSV

寫出為文字檔的範例1(不含欄位名稱)

use Student
copy to stu_info type DELIMITED

寫出為文字檔的範例2(不含欄位名稱)

use Student
copy to stu_info type SDF

使用技巧

抓取指定目錄下的所有檔案

counter=adir(testarray,'*.txt')
dimension myarray(counter,5)
counter=adir(myarray,'*.txt')
for i =1 to counter
   filename=myarray(i,1)
   ? filename
next

錯誤攔截

ON ERROR DO errhand WITH ERROR(), MESSAGE(), MESSAGE(1), PROGRAM( ),LINENO( ) && Trap OLE & other errors.
******************************************
* 說 明:錯誤處理程式
******************************************
PROCEDURE errhand
PARAMETER merror, mess, mess1, mprog, mlineno
CLEAR
IF merror=1426
mlineno=LTRIM(STR(LINENO()))
merror=LTRIM(STR(merror))
MESSAGEBOX("發生了一個OLE的錯誤,例如:呼叫的OLE程式重複開啟了檔案 "+CHR(13)+;
"Usually this is caused by quitting Word or canceling out of a dialog box in Word. "+CHR(13)+;
"錯誤訊息為:"+mess)
ELSE
mlineno=LTRIM(STR(LINENO()))
merror=LTRIM(STR(merror))
MESSAGEBOX("發生錯誤在程式第"+mlineno+"行"+CHR(13)+;
"錯誤訊息為:"+mess+" 錯誤代碼為"+merror)
ENDIF
ON ERROR
quit
RETURN

設定預設目錄

cCurrentProcedure = SYS(16,1)
nPathStart = AT(":",cCurrentProcedure)- 1
nLenOfPath = RAT("\", cCurrentProcedure) - (nPathStart) + 1
SET DEFAULT TO (SUBSTR(cCurrentProcedure, nPathStart, nLenofPath))

跳出對話視窗選擇檔案

gcXLS=GETFILE('XLS', '選擇或取消', '選擇', 0, '請選擇要處理的 Excel 檔')
DO CASE
   CASE EMPTY(gcXLS)
      Messagebox("並未選擇要處理的 Excel 檔",1+32,"訊息視窗")
      QUIT
   OTHERWISE
      ? "你選擇要處理的 Excel 檔是 "+gcXLS
ENDCASE

偵測目錄存在與否,若不存在則建立之

IF !DIRECTORY("tmp")
   MKDIR tmp
ENDIF

網路資源