 |
VFP 愛用者社區 本討論區為 Visual Foxpro 愛用者經驗交流的地方, 請多多利用"搜尋"的功能, 先查看看有無前例可循, 如果還有不懂的再發問. 部份主題有附加檔案, 須先註冊成為社區居民才可以下載.
|
| 上一篇主題 :: 下一篇主題 |
| 發表人 |
內容 |
CPS0204
註冊時間: 2014-08-24 文章: 537
第 1 樓
|
發表於: 星期五 八月 21, 2026 6:26 am 文章主題: vfox9 有關陣列的所有使用方法,函數介紹 |
|
|
在 Visual FoxPro 9 中,陣列(Array)是記憶體操作非常核心的一環。VFP 的陣列特性是:以 1 為基準(1-based)、單一陣列內可混合存放不同型別資料(數值、字元、日期、邏輯值甚至物件)、最多支援 二維(列與欄),且陣列內的所有元素共用變數池(MVCOUNT)。
以下為您整理 VFP 9 中關於陣列的宣告與賦值、內建高頻函數、以及與 Table/SQL 互轉的高階指令。
一、 陣列的宣告、賦值與基本特性
1. 宣告陣列
使用 DIMENSION、DECLARE 或搭配變數範圍關鍵字(LOCAL、PUBLIC、PRIVATE):
程式碼片段
* 一維陣列 (5 個元素,預設值皆為 .F.)
LOCAL laList[5]
* 二維陣列 (10 列 x 3 欄)
DIMENSION laMatrix[10, 3]
* 全域陣列宣告
PUBLIC gaPower[100, 2]
2. 賦值與批量初始化
程式碼片段
* 單一元素賦值
laList[1] = "ERP系統"
laMatrix[1, 1] = "A001"
laMatrix[1, 2] = 1500
* 批量全陣列賦值(直接對陣列名稱給值,所有元素都會變成該值)
laList = 0 && 所有 5 個元素一次歸零
laMatrix = "" && 所有 30 個元素一次清為空字串
二、 核心內建陣列函數一覽
函數名稱 核心功能 常用情境
ALEN() 取得陣列元素個數或維度大小 計算總元素數、總列數、總欄數
ASCAN() 快速搜尋陣列內容 尋找某數值/字串在陣列中的位置
ASORT() 陣列排序 依指定欄位升冪或降冪排序
AINS() 插入元素 / 插入列 陣列中插入空位(會擠掉最後一筆)
ADEL() 刪除元素 / 刪除列 刪除指定列(底層補空,需搭配 DIMENSION 縮容)
ACOPY() 複製陣列內容 將來源陣列複製到目的陣列
AELEMENT() 二維座標 $(R, C)$ 轉為一維元素序號 將 [列, 欄] 換算為單一 Index
ASUBSCRIPT() 一維元素序號轉為二維座標 $(R$ 或 $C)$ 搭配 ASCAN 查出該元素在第幾列
AFIELDS() 讀取目前資料表結構存入陣列 取得 Table 欄位名、型別、長度等中繼資料
ALINES() 將多行字串/文字依換行符號拆解進陣列 解析 Memo 欄位、文字檔或 SQL 語句
ADIR() 讀取硬碟目錄與檔案清單進陣列 檔案搜尋、抓取目錄下所有 .dbf / .scx
AERROR() 取得最後一次系統錯誤資訊 ON ERROR 或 TRY...CATCH 中抓取錯誤原因
APRINTERS() 取得 Windows 系統所有安裝的印表機清單 印表機動態切換、預設印表機選取
AFONT() 取得系統所有已安裝的字型名稱 UI 介面字型設定
AMEMBERS() 取得物件(Object)的所有屬性、方法與事件 反射(Reflection)機制、動態遍歷物件
三、 高頻核心函數詳解與實戰範例
1. ALEN(ArrayName [, nArrayAttribute]) — 計算長度與維度
• ALEN(laArr) 或 ALEN(laArr, 0):傳回總元素數量。
• ALEN(laArr, 1):傳回總列數(Rows)(一維陣列則傳回總元素數)。
• ALEN(laArr, 2):傳回總欄數(Columns)(若是一維陣列則傳回 0)。
程式碼片段
DIMENSION laData[50, 4]
? ALEN(laData) && 200 (總元素數)
? ALEN(laData, 1) && 50 (列數)
? ALEN(laData, 2) && 4 (欄數)
2. ASCAN(ArrayName, eExpression [, nStart [, nElements [, nColumn [, nFlags]]]]) — 陣列搜尋
這是 VFP 9 最強大的搜尋函數。VFP 9 支援第 6 個參數 nFlags,大幅簡化二維陣列查詢。
程式碼片段
DIMENSION laUser[3, 2]
laUser[1, 1] = "ADMIN"
laUser[1, 2] = "系統管理員"
laUser[2, 1] = "MIS01"
laUser[2, 2] = "資訊人員"
laUser[3, 1] = "SALES"
laUser[3, 2] = "業務專員"
* 傳統做法:ASCAN 傳回一維序號,再用 ASUBSCRIPT 轉成列號
lnElem = ASCAN(laUser, "MIS01")
IF lnElem > 0
lnRow = ASUBSCRIPT(laUser, lnElem, 1)
? "找到在第 " + STR(lnRow) + " 列,職稱是:" + laUser[lnRow, 2]
ENDIF
* VFP 9 推薦做法 (利用 nFlags = 15: 完全相符、精確比對、直接傳回列號,並指定只找第 1 欄)
* 語法:ASCAN(陣列, 搜尋值, 起始點, 搜尋範圍, 指定欄位, Flags)
lnRow = ASCAN(laUser, "MIS01", 1, -1, 1, 15)
IF lnRow > 0
? "直接取得列號:", lnRow && 輸出 2
ENDIF
3. ASORT(ArrayName [, nStart [, nElements [, nSortOrder [, nColumn]]]]) — 陣列排序
• nSortOrder:0 或省略為升冪(Ascending),1 為降冪(Descending)。
• nColumn:二維陣列指定以哪一欄作為排序基準。
程式碼片段
DIMENSION laScore[3, 2]
laScore[1, 1] = "張三"; laScore[1, 2] = 85
laScore[2, 1] = "李四"; laScore[2, 2] = 95
laScore[3, 1] = "王五"; laScore[3, 2] = 72
* 依第 2 欄(分數)進行「降冪排序」
ASORT(laScore, 1, -1, 1, 2)
4. ADEL() 與 AINS() — 刪除與插入列
⚠️ 重要觀念:VFP 的 ADEL 與 AINS 不會自動改變陣列大小!
• ADEL 只是將指定資料抹除並往前移,最後一筆會留下 .F.,因此刪除後必須手動 DIMENSION 縮小。
• AINS 插入空位時,會把最後一筆資料擠出陣列丟棄,因此插入前必須先 DIMENSION 放大。
程式碼片段
* 示範二維陣列安全刪除第 2 列:
DIMENSION laArr[3, 2]
ADEL(laArr, 2, 2) && 參數 2: 第 2 列; 參數 2: 代表以「列(Row)」為單位刪除
DIMENSION laArr[2, 2] && 重新定義縮小一列
5. ALINES(ArrayName, cText [, nFlags [, cParseChar]]) — 字串拆解進陣列
在處理 SQL 傳回的字串、文字檔、CSV 時極為常用:
程式碼片段
LOCAL lcStr, lnCount
lcStr = "蘋果,香蕉,芭樂,鳳梨"
* 依逗號拆解成一維陣列
lnCount = ALINES(laFruits, lcStr, 1, ",")
FOR i = 1 TO lnCount
? laFruits[i]
ENDFOR
四、 陣列與資料表(DBF / Cursor / SQL)的交互指令
VFP 提供了極為高效的命令,讓陣列能與資料庫記錄秒級互轉:
1. SELECT ... INTO ARRAY
直接將 SQL 查詢結果一次性倒入二維陣列中(若有符合資料,_TALLY 會記錄實際抓到的列數):
程式碼片段
SELECT CustID, CustName, Tel FROM Customer WHERE Status = 'A' INTO ARRAY laCust
IF _TALLY > 0
? "共載入 " + STR(_TALLY) + " 筆客戶資料"
? "第一筆客戶:", laCust[1, 2]
ENDIF
2. SCATTER TO 與 GATHER FROM(單筆資料錄與陣列互轉)
常用於單據畫面的「暫存、修改、還原」:
程式碼片段
USE Orders IN 0
SELECT Orders
* 將目前游標所在的那一筆紀錄,所有欄位值倒入一維陣列 laOrder
SCATTER TO laOrder MEMO
* 修改陣列中的值
laOrder[3] = 9999
* 將陣列值回寫覆蓋目前資料錄
GATHER FROM laOrder MEMO
3. COPY TO ARRAY 與 APPEND FROM ARRAY(多筆批次互轉)
適用於本地端 DBF / Cursor 與二維陣列進行大批量資料搬移:
程式碼片段
* 1. 將整張暫存表資料倒入陣列
SELECT cur_details
COPY TO ARRAY laDetails FIELDS ItemNo, Qty, Price FOR Qty > 0
* 2. 在另一張空 Cursor 中,一次性批次將陣列倒回資料表
SELECT cur_target
APPEND FROM ARRAY laDetails
五、 陣列在 VFP 9 中的限制與注意事項
1. 二維限制:VFP 僅支援最多二維陣列 [Row, Col],不支援三維以上。若需要多層巢狀結構,建議改用物件(EMPTY Object)或 Collection。
2. 容量上限:VFP 9 單一陣列的元素總數量上限為 2,000,000(200 萬個元素)。
3. 變數池佔用(MVCOUNT):
o 陣列中的每一個元素都會消耗一個變數計數。
o 若經常使用大型陣列(如 [1000, 10] 消耗 10,000 個變數),必須在 Config.fpw 中配置 MVCOUNT = 65000,避免觸發 Too many variables。
4. 傳遞陣列至 Procedure / Function:
o VFP 預設是傳值(By Value),只會傳遞陣列的「第一個元素 laArr[1]」。
o 若要傳遞整個陣列,必須在名稱前加上 @ 符號(傳址 By Reference):
程式碼片段
DIMENSION laMyData[5]
= ProcessData(@laMyData) && 加上 @ 才會將整個陣列傳入 |
|
| 回頂端 |
|
 |
|
|
您 無法 在這個版面發表文章 您 無法 在這個版面回覆文章 您 無法 在這個版面編輯文章 您 無法 在這個版面刪除文章 您 無法 在這個版面進行投票 您 無法 在這個版面附加檔案 您 無法 在這個版面下載檔案
|
|