גישה לנתוני טבלה - קריאה ועריכה
לאחר שיצרת טבלה וטענת לתוכה נתונים, השלב הבא הוא גישה לערכים שנמצאים בתוכה.במערכת התסריטים של הייפר, הגישה לנתוני טבלה מתבצעת ישירות דרך אובייקט הטבלה מסוג ThTable או ThPrvTable.
הטבלה בנויה משורות ועמודות: כל עמודה מייצגת שדה, וכל שורה מייצגת רשומה.
בעמוד זה נלמד כיצד לקרוא ערכים, כיצד לערוך ערכים, ומה ההבדל בין גישה לפי שם שדה באמצעות Field לבין גישה לפי מספר עמודה באמצעות Cell.
הערות:
- בדוגמאות בעמוד זה נעשה שימוש בטבלה בשם ClientTb, אך אותו עיקרון נכון לכל אובייקט טבלה.
- מספור השורות והעמודות מתחיל מ־0.
-
כאשר מעבירים ערך שורה -1, המערכת משתמשת בשורה הפעילה הנוכחית של הטבלה.
- שינוי ערך בטבלה משנה את אובייקט הטבלה המקומי בזיכרון. שמירה למסד הנתונים היא פעולה נפרדת מול Server/DBconn.
מבנה הגישה לשורה ועמודה
כל ערך בטבלה נמצא במיקום המורכב משני חלקים:עמודה - השדה שבו נמצא הערך.
שורה - הרשומה שבה נמצא הערך.
| מושג | הסבר יישום |
|---|---|
| Col / X | מספר העמודה בטבלה. העמודה הראשונה היא 0. |
| Row / Y | מספר השורה בטבלה. השורה הראשונה היא 0. |
| Row | השורה הפעילה הנוכחית של הטבלה. |
| RowCount | מספר השורות הקיימות כרגע בטבלה. |
| ColCount | מספר העמודות הקיימות בטבלה. |
דוגמה:
ClientTb.Row:= 0;
Fman.SB_Message('Rows: ' + IntToStr(ClientTb.RowCount), False);
Fman.SB_Message('Columns: ' + IntToStr(ClientTb.ColCount), False);
הערך
-1
בפרמטר השורה הוא קיצור לשורה הפעילה הנוכחית של הטבלה.
Field - גישה לפי שם שדה
הדרך הקריאה והמומלצת ברוב התסריטים היא גישה לפי שם שדה.בגישה זו כותבים את שם השדה כפי שהוא מופיע בטבלה, ואת מספר השורה שממנה רוצים לקרוא או שאותה רוצים לערוך.
TableName.Field['Field Name', Row]
| חלק בפקודה | הסבר יישום |
|---|---|
| Field Name |
שם השדה בטבלה.
לפי המימוש בקוד, המערכת מחפשת את השדה גם לפי שם שדה רגיל וגם לפי שם Json אם הוגדר. |
| Row |
מספר השורה. הערך -1 מציין את השורה הפעילה הנוכחית.
|
דוגמת קריאה:
VAR ClientName: String;
Begin
ClientName:= ClientTb.Field['Client Full Name', 0];
Fman.SB_Message(ClientName, False);
End;
דוגמת עריכה:
ClientTb.Field['Remarks', 0]:= 'Checked by script';
אם שם השדה אינו קיים בטבלה, הקריאה תחזיר ערך ריק או 0 בהתאם לסוג הגישה, והמערכת תרשום הודעת שגיאה למפתח.
לכן כאשר שם השדה יכול להשתנות או להגיע מבחוץ, מומלץ לבדוק אותו לפני השימוש.
IF ClientTb.FldSet.Field_Exist('Client Full Name') Then
Fman.SB_Message(ClientTb.Field['Client Full Name', 0], False);
Cell - גישה לפי מספר עמודה
גישה באמצעות Cell מתבצעת לפי מספר עמודה ומספר שורה.זו גישה קצרה ומהירה כאשר עובדים בלולאות, בטבלאות פרטיות, או כאשר ידוע מראש סדר העמודות.
TableName.Cell[Column, Row]
| חלק בפקודה | הסבר יישום |
|---|---|
| Column | מספר העמודה בטבלה. העמודה הראשונה היא 0. |
| Row |
מספר השורה. הערך -1 מציין את השורה הפעילה הנוכחית.
|
דוגמה:
VAR FirstValue: String;
Begin
FirstValue:= ClientTb.Cell[0, 0];
Fman.SB_Message(FirstValue, False);
End;
כאשר משתמשים ב־Cell, האחריות היא על כותב הקוד לדעת איזו עמודה נמצאת בכל אינדקס ולקחת בחשבון אפשרות לשינוי סדר העמודות בעתיד.
אי לכך, בקוד עסקי רגיל מומלץ לתת עדיפות לשימוש ב־Field.
Cell מתאים כאשר מדובר בקוד זמני, ייצוא, סריקה בלולאות, חישובים על טווח עמודות, או טבלה פרטית שבה סדר העמודות ידוע ונשלט על ידי התסריט.
סיכום ההבדל:
| גישה | מבנה כתיבה | מתי להשתמש |
|---|---|---|
| Field | Table.Field['Field Name', Row] | כאשר חשוב שהקוד יהיה ברור ועמיד לשינוי סדר העמודות. |
| Cell | Table.Cell[Column, Row] | כאשר עובדים לפי מספרי עמודות, בלולאה, בייצוא, או בטבלה פרטית שבה סדר העמודות ידוע ונשלט על ידי התסריט. |
שתי הקריאות הבאות יכולות להחזיר את אותו ערך, אם העמודה 0 היא השדה Client Number:
ClientNumber:= ClientTb.IField['Client Number', 0];
ClientNumber:= ClientTb.ICell[0, 0];
סוגי הגישה לערכים
לכל גישה לפי Field קיימת גישה מקבילה לפי Cell.הקידומת קובעת באיזה טיפוס נתונים התסריט יקבל או יכתוב את הערך.
| לפי שם שדה | לפי עמודה | טיפוס החזרה | שימוש עיקרי |
|---|---|---|---|
| Field | Cell | String | קריאה או כתיבה כטקסט. בערכים מספריים ותאריכים מתקבל טקסט מפורמט לפי הגדרות השדה. |
| IField | ICell | Int64 | מספר שלם. מתאים לשדות מספריים שלמים, סטטוסים, מפתחות ורשומות מקושרות. |
| RField | RCell | ThNumeric | מספר ממשי. מתאים לכסף, אחוזים, ערכים עשרוניים ותאריכים/שעות כאשר צריך לשמור גם חלקי זמן. |
| BField | BCell | Boolean | בדיקת קיום ערך או קריאה/כתיבה של שדה בוליאני. |
| Flag | CFlag | Boolean | דגל פנימי של התא, המשמש בעיקר לסימון ועיבוד מקומי בתוך הטבלה. |
שים לב: IField מחזיר מספר שלם ולכן הוא חותך חלק עשרוני.
כאשר עובדים עם שדה FixDT, שעה, כסף או מספר עשרוני, בדרך כלל נכון להשתמש ב־RField כדי לא לאבד דיוק.
המרת נתונים מובנית בגישה לשדות
בהמשך לטבלת סוגי הגישה, חשוב להבין שהגישה לשדות כוללת מנגנון המרה מובנה.אותו ערך בתא יכול להיקרא כטקסט, כמספר שלם, כמספר ממשי או כבדיקת קיום ערך, בהתאם לסוג הגישה שבחרת.
המנגנון אינו משנה את סוג השדה המקורי בטבלה, אלא רק קובע כיצד הערך יוחזר לתסריט או כיצד ערך חדש יומר בזמן כתיבה.
קריאת מספר כשדה טקסט
כאשר קוראים שדה מספרי באמצעות Field, מתקבל טקסט.
לדוגמה, אם Client Number הוא שדה מספרי, עדיין ניתן לקרוא אותו למשתנה String:
VAR S: String;
Begin
S:= ClientTb.Field['Client Number', -1];
End;
במקרה כזה המערכת ממירה את הערך המספרי לטקסט.
הטקסט שמתקבל מושפע מסוג השדה ומהגדרות התצוגה שלו.
אם דרוש לך הערך המספרי לחישוב, עדיף לקרוא אותו באמצעות IField או RField. קריאת DateTime כטקסט או כמספר
שדה מסוג FixDT או שעה יכול להיקרא בשתי צורות עיקריות:
VAR S: String;
D: ThNumeric;
Begin
S:= ServTicket.Field['Created On', -1];
D:= ServTicket.RField['Created On', -1];
End;
המשתנה S יקבל טקסט מפורמט להצגה או לפלט.
המשתנה D יקבל את הערך הנומרי המלא, שמתאים להשוואות, חישובים והעברה לפקודות Where.
לעומת זאת, שימוש ב־IField על שדה FixDT מחזיר מספר שלם:
VAR MyNum: Integer;
Begin
MyNum:= ServTicket.IField['Created On', -1];
End;
קוד כזה תקין מבחינת טיפוסים, אך הוא מאבד את החלק העשרוני של הערך.
בשדה FixDT החלק העשרוני מייצג את רכיב השעה, ולכן בדרך כלל זו לא הגישה הנכונה אם צריך תאריך ושעה מלאים. כתיבת טקסט לשדה שאינו טקסט
גם בזמן כתיבה קיימת המרה מובנית.
כאשר כותבים דרך Field, המערכת מקבלת String ומנסה להמיר אותו לסוג השדה בפועל.
לדוגמה:
ClientTb.Field['Client Number', 0]:= '1001';
ServTicket.Field['Created On', 0]:= '01/05/2026 08:30:00';
InvoiceTb.Field['Total Amount', 0]:= '1250.75';
בדוגמאות אלו הכתיבה מתבצעת כטקסט, אך השמירה הפנימית בתא מתבצעת לפי סוג השדה.
כאשר הערך כבר קיים בתסריט כמספר או כתאריך נומרי, עדיף להשתמש בגישה המתאימה:
ClientTb.IField['Client Number', 0]:= 1001;
ServTicket.RField['Created On', 0]:= Save_FixDT_Filter('01/05/2026 08:30:00', he_AutoDetect);
InvoiceTb.RField['Total Amount', 0]:= 1250.75;
כלל אצבע
- אם הערך מיועד להצגה, הדפסה או חיבור לטקסט, השתמש ב־Field.
- אם הערך הוא מפתח, סטטוס או מספר שלם, השתמש ב־IField.
- אם הערך הוא כסף, מספר עשרוני, שעה או FixDT, השתמש ב־RField.
- אם צריך לבדוק האם יש ערך בשדה, השתמש ב־BField.
קריאת נתונים מטבלה
לפני קריאת נתונים מומלץ לבדוק שהטבלה אינה ריקה.לאחר מכן ניתן לגשת לשורה הרצויה לפי מספרה, או להגדיר את Row ולהשתמש ב־
-1
.
IF ClientTb.Empty(0) Then EXIT;
ClientName:= ClientTb.Field['Client Full Name', 0];
ClientNumber:= ClientTb.IField['Client Number', 0];
Balance:= ClientTb.RField['Balance', 0];
קריאה מהשורה הפעילה:
ClientTb.Row:= 0;
ClientName:= ClientTb.Field['Client Full Name', -1];
ClientNumber:= ClientTb.IField['Client Number', -1];
מעבר על כל הרשומות בטבלה:
VAR Y: Integer;
Begin
IF ClientTb.Empty(0) Then EXIT;
For Y:= 0 To ClientTb.RowCount-1 Do
Begin
Fman.SB_Message(ClientTb.Field['Client Full Name', Y], False);
End;
End;
בדיקת קיום ערך באמצעות BField
כפי שראינו בפרק ההמרות, BField שימושי כאשר רוצים לדעת אם בשדה יש ערך.לפי המימוש בקוד, ההתנהגות תלויה בסוג השדה:
בטקסט הוא בודק שהטקסט אינו ריק, במספרים הוא בודק שהערך אינו 0, ובשדה בוליאני הוא מחזיר את ערך השדה עצמו.
דוגמה:
IF ClientTb.BField['Mobile Phone', 0] Then
Fman.SB_Message(ClientTb.Field['Mobile Phone', 0], False);
IF NOT ClientTb.BField['ID Number', 0] Then
Fman.SB_Message('ID Number is missing.', True);
לכן אין להתייחס ל־BField רק כאל קריאה של שדה Bool; ברוב סוגי השדות הוא משמש גם כבדיקת "האם יש ערך".
עריכת נתונים בטבלה
כתיבה לשדה מתבצעת באמצעות השמה ישירה לאותה גישה שבה משתמשים לקריאה.| קוד | הסבר יישום |
|---|---|
| ClientTb.Field['Remarks', 0]:= 'Checked by script'; | כתיבת טקסט לשדה לפי שם שדה. |
| ClientTb.IField['Status', 0]:= 2; | כתיבת ערך מספרי שלם. |
| ClientTb.RField['Balance', 0]:= 1250.75; | כתיבת ערך מספרי עשרוני. |
| ClientTb.BField['Blocked', 0]:= True; | כתיבת ערך בוליאני. |
דוגמה מלאה לעריכה מקומית:
IF ClientTb.Empty(0) Then EXIT;
ClientTb.Field['Remarks', 0]:= 'Updated by script';
ClientTb.IField['Status', 0]:= 1;
ClientTb.Modified_By_User:= True;
שינוי הערכים מתבצע בזיכרון המקומי של הטבלה.
כדי לשמור את השינוי למסד הנתונים יש לבצע פעולת שמירה מתאימה מול Server/DBconn, בהתאם לסוג הטבלה והרשאות העריכה.
Server.Reset;
Server.Save(ClientTb, [], 'N');
IF NOT Server.Execute Then EXIT;
נושא שמירת נתונים למסד הנתונים רחב יותר מעריכת תאים מקומית, ולכן יש להתייחס לדוגמה זו כתבנית בסיסית בלבד.
הוספת שורה ועבודה עם טבלה פרטית
לאחר GlobalInit או Clear, טבלה תקינה מכילה שורה ריקה אחת עם ערכי ברירת מחדל.לכן כאשר רוצים למלא טבלה ריקה, ניתן לכתוב ישירות לשורה 0.
כאשר רוצים להוסיף רשומה נוספת, משתמשים ב־Add ולאחר מכן כותבים לשורה הפעילה.
VAR WorkTb: ThPrvTable;
Begin
WorkTb:= Fman.Create_PrvTable('hyp_Clients', 'WorkTb', ['Client Number', 'Client Full Name'], False);
WorkTb.GlobalInit;
WorkTb.IField['Client Number', 0]:= 1001;
WorkTb.Field['Client Full Name', 0]:= 'First Client';
WorkTb.Add;
WorkTb.IField['Client Number', -1]:= 1002;
WorkTb.Field['Client Full Name', -1]:= 'Second Client';
End;
בדוגמה זו, אחרי Add השורה הפעילה היא השורה החדשה שנוספה, ולכן ניתן להשתמש ב־
-1
.
טעויות נפוצות
| טעות | הסבר ותיקון |
|---|---|
| שימוש ב־Cell כאשר סדר העמודות לא ידוע |
אם סדר העמודות משתנה, Cell עלול לקרוא שדה אחר מהמצופה.
בקוד עסקי רגיל עדיף להשתמש ב־Field לפי שם שדה. |
| שימוש ב־IField לשדה FixDT |
IField מחזיר מספר שלם ולכן עלול לאבד את רכיב השעה.
עבור FixDT או Hour השתמש ב־RField. |
| קריאה מטבלה לפני בדיקת Empty | לפני עבודה על תוצאות Query מומלץ לבדוק שהטבלה אינה ריקה. |
| שימוש בשם שדה שגוי |
שם שדה שגוי לא יפנה לעמודה תקינה.
כאשר יש ספק, בדוק באמצעות FldSet.Field_Exist. |
| עריכת טבלה ללא שמירה |
השמה לתא משנה את הטבלה המקומית בזיכרון.
שמירה למסד הנתונים דורשת פעולת Save/Update מתאימה מול Server/DBconn. |
תבניות קוד קצרות
קריאת שדה טקסט:ClientName:= ClientTb.Field['Client Full Name', 0];
קריאת מספר:
ClientNumber:= ClientTb.IField['Client Number', 0];
קריאת DateTime מלא:
CreatedOn:= ServTicket.RField['Created On', 0];
בדיקת קיום ערך:
IF ClientTb.BField['Mobile Phone', 0] Then
Phone:= ClientTb.Field['Mobile Phone', 0];
עריכת שדה:
ClientTb.Field['Remarks', 0]:= 'Updated by script';
מעבר על כל הרשומות:
For Y:= 0 To ClientTb.RowCount-1 Do
Fman.SB_Message(ClientTb.Field['Client Full Name', Y], False);