תהיה בריא.
לא ניסיתי לשכנע, שים לב.
פורסם במקור בפורום CODE613 ב23/12/2013 14:18 (+02:00)
הפורום כעת לקריאה בלבד, לקריאה נוספת.
תהיה בריא.
לא ניסיתי לשכנע, שים לב.
פורסם במקור בפורום CODE613 ב23/12/2013 14:18 (+02:00)
@דוד ל.ט.
לבעיה שכתבת אתה צריך לקבוע את _id (לפי מקור נתוניך) מתוך קונסטרקטור סטטי:אולי זה מה שאתה מתכוון אבל אני הגדרתי שהמאפיין ID הוא לא לקריאה לבד, ואז כאשר אני קורה מהדיסק את הנתונים אני נותן ערך ל ID של כל רשומה ורשומה כמו שהיה לה בריצה הראשונה, ורק בדטה גריד אם אני מציג את העמודה של ה ID היא לקריאה בלבד.
לא הבנתי אותך. אני התייחסתי בכל אופן לקוד שהעלתי לעיל. לא אמורה להיות בעיה גם אם המאפיין הוא לקריאה בלבד, כי השדה הפנימי הוא פתוח לכתיבה.
אנא נסה לא להיות עוד כטוען בחיטים ומודה בשעורים... זה הרי ברור כשמש שלא התכוונתי למה שעשית (שדרך אגב, זה מצויין לגמרי, רק שעדיף למנוע שינוי בטעות אף בתוך הקוד מחוץ למחלקה).
@דוד ל.ט.
אבל זה ממש לא פיתרון טוב עבור מסד נתונים, מכמה וכמה סיבות.תוכל לפרט בבקשה אני חייב לדעת.
אתה בטוח שאתה חייב לדעת? מה אם אומר לך שאיני יודע? הנושא הזה הוא יכול להילמד כמה שנים באוניברסיטה. אבל לא בשביל כל מסקנה אני חייב לדעת את ה"הוכחה" כתובה, ואני חושב שגם אתה לא חייב.
דומני שאתה יכול לשער בנפשך שלא נבראו מסדי נתונים רק בשביל מתכנתים עצלנים באופן יוצא מן הכלל, אלא לעוד כמה סיבות טובות.
אם אתה רוצה משל: חשוב מה קורה שאתה מפעיל את התוכנה פעמיים ומעדכן בשניהם. זה בעיונת טפשונת שניתנת לפיתרון קל, אבל עוד כמה כאלה ואתה מגיע למסקנתי.
@דוד ל.ט.
אם זה ממש מסד, אל תטפל במספור אוטומטי, בשביל מה לך.אני חייב שיהיה לי מזהה יחודי לכל רשומה בטבלה
אם זה כדי שלכל אלמנט יהיה זיהוי, אתה יכול להשתמש בשמו.
אלא איך אפשר אחרת?
@רחמים
כך שזה מסד לכל דבר רק בלא SQL ובלא דטה-סיט ובלא אקסס.
פורסם במקור בפורום CODE613 ב23/12/2013 11:31 (+02:00)
נ.ב
צריך לתקן בקוד במקום Return ID
Return _id
נכון, התבלבלתי.
לבעיה שכתבת אתה צריך לקבוע את _id (לפי מקור נתוניך) מתוך קונסטרקטור סטטי:
Shared Sub New()
'read file from disk
'and set _id = max + 1
End Sub
אבל זה ממש לא פיתרון טוב עבור מסד נתונים, מכמה וכמה סיבות.
אם זה ממש מסד, אל תטפל במספור אוטומטי, בשביל מה לך.
פורסם במקור בפורום CODE613 ב22/12/2013 20:39 (+02:00)
תוסיף לאובייקט שלך (כמו האנשי קשר) שדה סטטי שיספור איפה אוחזים.
בבנאי תקצה את המספר הפנוי. ככה:
Shared inc As Integer
Dim _id As Integer
Public ReadOnly Property ID
Get
Return ID
End Get
End Property
Public Sub New()
_id = inc
inc += 1
End Sub
פורסם במקור בפורום CODE613 ב19/12/2013 22:19 (+02:00)
הצורה היחידה שהוא עובד זה רק אם אני מגדיר את בSortMemberPath ל SelectedValueBinding, אלא שאז הוא ממיין את המזהים ולא מה שמוצג על המסך בתוך כל תא.
זה אמור לקרות גם אם לא הגדרת את SortMemberPath כלל.
אני לא מצליח לעזור לך. רק לפחות תידע איפה לחקור אז אני מכוון אותך מה אמורים לעשות.
למה אצלך לא עובד זה מה שנשאר לחקור אבל לכה"פ צמצמתי לך את החפירה.
בדרך אגב, אף פעם אל תחסוך בהעלאת קוד (רלוונטי כמובן), כי גם אם הוא תקין, אתה מרויח שנחסך דיון עליו.
פורסם במקור בפורום CODE613 ב22/12/2013 20:54 (+02:00)
לא ברור מדבריך איך עשית.
בSortMemberPath אתה אמור להכניס "שם פרטי".
שים לב שחלק מהמאפיינים מקבלים מחרוזת טקסט פשוטה,
וחלק Binding מלא (אלו שמכילים את המילה הזאת בשמם).
פורסם במקור בפורום CODE613 ב22/12/2013 19:00 (+02:00)
כוונתי? היא כ"כ עמוקה :)?
אתה אמרת שניסית את המאפיין SortMemberPath ובגלל זה זה לא עבד בכלל.
על זה אמרתי שאכן זו הדרך הנכונה ועליך לבדוק למה זה לא עובד.
אתה כתבת בו את הסטרינג Name?
פורסם במקור בפורום CODE613 ב19/12/2013 22:22 (+02:00)
SortMemberPath עושה את מה שאתה רוצה.
תנסה לבדוק שהכל תקין. לדוגמא, שנה את גם הDisplayMemeberPath לאותו שם שהקצית לSortMemberPath.
פורסם במקור בפורום CODE613 ב19/12/2013 21:28 (+02:00)
לא, אני לא יודע כרגע.
גם ראיתי שיש DataGridComboBoxColumn אז אולי עדיף להשתמש בו במקום ב TemplateColumn ?
נכון, לגמרי שכחתי.
תמיד עדיף לחסוך אז אם אין לך דרישות מיוחדות תשתמש בו.
ההגדרות הדרושות במרבית המקרים הם הללו:
[u:j23yn1zl]א. הגדרות התיבת רשימה ברמת הפקד, אחיד לכל השורות.[/u:j23yn1zl]
[u:j23yn1zl]ב. הגדרות ברמת שורה:[/u:j23yn1zl]
כעת מה שחשוב זה לקבוע מה הערך הנבחר = על איזה נתון ברמת השורה הוא מושפע ומשפיע.
ישנם שתי דרכים. במידה וItemsSource מכיל איברים בני אותו הסוג של השדה ברמת השורה,
יש להשתמש עם SelectedItemBinding בו יש לקבוע את האיגוד מרמת השורה. יש לשים לב שזה בינדינג לכל דבר: בחירה מהרשימה תכתוב לתוך הערך ולהיפך.
במידה והשדה מהשורה הוא מסוג אחר מסוג הפריטים ברשימה, למשל ID של האובייקט, שזה מספר ולא אובייקט,
יש לקבוע
א. SelectedValuePath בו נקבע איזה שדה מתוך האובייקט נחשב הערך הנבחר.
ב. SelectedValueBinding שזה איגוד מהשדה ברמת השורה לערך הנבחר (ה"ערך" נחשב השדה שנכתב בSelectedValuePath. אם לא נכתב שדה, אז זה מחזיר את כל האובייקט בדומה לאפשרות א).
פורסם במקור בפורום CODE613 ב19/12/2013 13:58 (+02:00)
אני מבין שבאופן כללי, שלא בתוך דטה גריד, אתה יודע לעשות תיבה משולבת עם ערכים דינמיים, ועם איגוד הנבחר למאפיין.
אז פשוט צריך לעשות את זה בתוך הTemplateColumn.
פורסם במקור בפורום CODE613 ב19/12/2013 11:04 (+02:00)
הסיבה היא בגלל שהאחריות לבינדינג בעמודת DataGridTemplateColumn
היא לגמרי על המתכנת. אז גם מחלקת DataGridTemplateColumn מאוד רוצה, אין לה מושג לפי מה למיין.
בשביל זה עשו מאפיין מיוחד SortMemberPath. במקרה שלך תכתוב SortMemberPath="myDate".
פורסם במקור בפורום CODE613 ב18/12/2013 20:19 (+02:00)
השגיאה הזאת בעצם אומרת, אני לא יודעת מה קרה, אבל תכלס לא נעשו שינויים במסד אפי' שלטעמי היו צריכים להיעשות.
במקרה זה היא מצביעה שהייתה שורה אחת שאמורה להיות מושפעת, ובכל אופן המסד אמר ש0 שורות הושפעו.
מה שחשוב לראות זה מה קרה באמת במסד, ייתכן שפשוט מנסים למחוק פעמיים אותה שורה וכו'.
כדאי גם לעקוב אחרי שורה ספציפית ולראות את מצבה לפני הUpdate. מצבה אני מתכוון לRowState שלה.
במקרה זה הבדיקה תהיה ע"י BreakPoint בשורת הUpdate, וכתיבה ב Immediate window:
? dts.childarenTable.GetChange().Rows[0].RowState
בנוסף, הערה על הקוד שלך:
עשית לולאה מאוד טריקית. היא מוחקת כל פעם שורה ראשונה, ועושה זאת שוב אם ישנם עוד שורות.
היא גם מפעילה על כל איטרציה פעמיים פונקציה GetXXXRows.
דרך טבעית יותר זה ככה:
foreach (var row in teudaLetipul.GetGetParentTableRows())
{
item.Delete();
}
פורסם במקור בפורום CODE613 ב18/12/2013 20:38 (+02:00)
תודה רבה! לא ידעתי כלל.
פורסם במקור בפורום CODE613 ב17/12/2013 10:52 (+02:00)
עדיין לא מבין, אם להשתמש בפונקציית האירוע, כפונקציה רגילה, אז עושים אחת אחרת וקוראים לה גם מהאירוע וגם מכל מקום בו רוצים את פונקציונליות הפרמטרים הנוספים.
נכון שאם היה אפשר אז זה היה "שתיים במכה אחת", אבל זה העמסה טריקית של שתי שימושים חסרי קשר.
ההסבר שלך רחמים ממש לא מתייחס לתמיהתי אלא מפרש מה הבעיה. הפירוש גם איננו נכון, לא זמן הקישור (AddHandler) קובע את מס' הפרמטרים, אלא הכרזת האירוע במחלקה שהכריזה אותו.
שים לעובדה שבVBA אין בכלל AddHandler אלא הפונקציות מקושרות לפי שם שמור כסטרינג.
פורסם במקור בפורום CODE613 ב11/12/2013 11:13 (+02:00)
זוהי שאלה משוללת הבנה.
באירוע יש צד משדר (שמעיר את האירוע בזמן המתאים) וצד מאזין (כמו הפרוצדורה Form_Load שמוקפצת כאשר אירוע הטעינה מתרחש).
הצד המשדר קובע את הפרמטרים שדרושים לפונקציה, והוא דואג לאכלס אותם בערכים האקטואליים.
כשאתה בצד המאזין, אין שום סיבה שתרצה לשים פרמטר בפרוצדורת האירוע, כי מי ימלא אותו?
אם אתה עצמך קורא לפרוצדורה זו ככל פרוצדורה אחרת, אז למה להשתמש בה (שמשמשת להאזנה לאירוע) ולא לכתוב אחרת?
אחרי שאני קורא את הטריק של רחמים, אני מבין שאולי באמת כוונתך לשלוח פרמטר לטופס בעת יצירתו.
אם ככה אתה אמור להשתמש בפרמטר בקונסטרקטור, ובאמת בVBA אני לא יודע איך עושים זאת, יעויין http://stackoverflow.com/questions/15224113/pass-arguments-to-constructor-in-vba
פורסם במקור בפורום CODE613 ב10/12/2013 14:36 (+02:00)
א. הפרמטר RelationDataSet זה שם הדטה סט ששימש את המחקר..
ב. מקוה שאתה מבין מה המשתנה הראשון. אם לא הבנת נסה שוב.
ג. השאילתה הנ"ל מחזירה את הID האחרון ש"הומצא" ע"י המערכת בתקשורת (Connection) הנוכחית.
פורסם במקור בפורום CODE613 ב12/12/2013 14:21 (+02:00)
תודה רבה!
@דוד ל.ט.
ואף אולי אשאל את השאלה ליתר ביטחון בפורום Stackoverflow.מתי יתחילו לעלות לכאן שאלות שמתקשים בהם ב - Stackoverflow ?...

ובכן היום גמרתי את החקירה והדרישה.
דבר ראשון, קוד שפותר את הבעיה:
private void UpdateX2(RelationDataSet ds)
{
var daCat = new RelationDataSetTableAdapters.CategoriesTableAdapter();
var connOleDb = daCat.Connection;
var cmdRetId = new System.Data.OleDb.OleDbCommand("SELECT @@IDENTITY", connOleDb);
connOleDb.Open();
foreach (var row in ds.Categories.Where(r => r.RowState == System.Data.DataRowState.Added))
{
//מכניס שורות שנוספו אחת אחת ומבצע שאילתה לקבל את הקוד
daCat.Update(row);
row.ID = (int)cmdRetId.ExecuteScalar();
row.AcceptChanges();
//עדכון בנים
foreach (var childRow in row.GetProductsRows() )
{
childRow.Category = row.ID;
}
}
//לעדכון שאר השורות (נמחקו/שונו)
daCat.Update(ds.Categories);
connOleDb.Close();
}
הקוד הזה הוא חלופה לעדכון הרגיל.
הוא מעדכן שורה שורה בטבלת האב ומריץ שאילתה לדעת את הקוד שהשורה קיבלה.
אם שורת הבן נוספה לפני העדכון, הפונקציה מעדכנת לה את קוד שורת האב,
ואם השורה נוספת אחרי העדכון יש לעדכן ידנית את קוד שורת האב.
טוב, עכשיו נשארת השאלה למה הצרה הזו עם אקסס?
תשובה: בניגוד לSQL SERVER והרבה מסדי נתונים אחרים, באקסס פקודת SQL חייבת מורכבת מפקודה אחת בלבד.
ממילא חייבים להריץ כזו שאילתה נפרדת. כיון שזה נפרד, אין שום מנגנון פנימי שיקבל את התוצאות ויציב אותם בדטה סט.
עוד משהו:
כל זה נדרש במספור אוטומטי צד מסד.
כלומר במידה ואסור לתוכנה לקבוע את המספר, בגלל שלמשל יש כמה משתמשים בו זמנית (התנגשות מספרים).
אחרת ניתן לקבוע עדכון גם לשורת הID, ולקבוע את הערכים של המספור אוטומטי לגידול של1 (במקום -1 לשורות זמניות), ולקבוע בפקודת הInsert גם את הID.
במידה וכך, אז החיים ממש פשוטים.
פורסם במקור בפורום CODE613 ב11/12/2013 13:34 (+02:00)
אחרי חיפוש קדחתני אחרי מה שהיה זכור לי כפתיר בקלי קלות,
הגעתי למסקנות עגומות.
המסקנות הם: בSQL SERVER ובמסדי נתונים דומים, זה באמת קל, אם כי צריך להגדיר שהדטה סט יתחכם לעדכן את הבנים במס' של האבות.
אבל באקסס, אי אפשר, כלומר מוכרחים לאחזר את המספר ידנית ולקבוע אותו בשורה שמועמדת להיות הבן...
כך יצא לי לבינתיים.
מחר אולי אפרט, ואף אולי אשאל את השאלה ליתר ביטחון בפורום Stackoverflow.
פורסם במקור בפורום CODE613 ב10/12/2013 18:16 (+02:00)
אולי תנסה להתייחס לזה כמסמך וורד.
פורסם במקור בפורום CODE613 ב08/12/2013 14:37 (+02:00)
לא ידעתי שיש כזה דבר הערות שוליים בRTF.
הכתבן מציג אותם?
פורסם במקור בפורום CODE613 ב08/12/2013 12:29 (+02:00)