למומחי אקסל /אקסס

ממוו

משתמש רשום
יש לי טבלה ובה רשימת לקוחות שכל אחד מזוהה ע"י מספר ורשום לו פרטים שונים למשל כל הפעולות שעשה הלקוח, כשכל פעולה מופיעה בשורה נפרדת שמתחילה במזהה לקוח.
אני מעונין ליצור טבלה שבה יהיה רשום כל לקוח בשורה אחת ובה יהיה רשום בזה אחר זה כל הפעולות של הלקוח.
לדוגמא
לקוח 1234= ביום א' קנה חלב, ביום ב' קנה חלב, ביום ב' קנה לחם, וכו' וכו'
לקוח 2012= ביום א' קנה לחם, ביום ב' קנה בית.
כשלכל לקוח יש כמות נתונים משתנה.
האם יש למישהו דרך לעשות את זה באקסס? או באקסל. (עדיף לי באקסס.)
תודה רבה מראש לכל המסייעים
 

FullTime

משתמש מקצוען
קרדיט ל @moishy
תוסיף את הקוד הזה למודול חדש.:
קוד:
Option Compare Database

Public Function ConcatRelated(strField As String, _
    strTable As String, _
    Optional strWhere As String, _
    Optional strOrderBy As String, _
    Optional strSeparator = ", ") As Variant
On Error GoTo Err_Handler
    'Purpose:   Generate a concatenated string of related records.
    'Return:    String variant, or Null if no matches.
    'Arguments: strField = name of field to get results from and concatenate.
    '           strTable = name of a table or query.
    '           strWhere = WHERE clause to choose the right values.
    '           strOrderBy = ORDER BY clause, for sorting the values.
    '           strSeparator = characters to use between the concatenated values.
    'Notes:     1. Use square brackets around field/table names with spaces or odd characters.
    '           2. strField can be a Multi-valued field (A2007 and later), but strOrderBy cannot.
    '           3. Nulls are omitted, zero-length strings (ZLSs) are returned as ZLSs.
    '           4. Returning more than 255 characters to a recordset triggers this Access bug:
    '               http://allenbrowne.com/bug-16.html
    Dim rs As dao.Recordset         'Related records
    Dim rsMV As dao.Recordset       'Multi-valued field recordset
    Dim strSql As String            'SQL statement
    Dim strOut As String            'Output string to concatenate to.
    Dim lngLen As Long              'Length of string.
    Dim bIsMultiValue As Boolean    'Flag if strField is a multi-valued field.
  
    'Initialize to Null
    ConcatRelated = Null
  
    'Build SQL string, and get the records.
    strSql = "SELECT " & strField & " FROM " & strTable
    If strWhere <> vbNullString Then
        strSql = strSql & " WHERE " & strWhere
    End If
  
    If strOrderBy <> vbNullString Then
        strSql = strSql & " ORDER BY " & strOrderBy
    End If
  
    Set rs = DBEngine(0)(0).OpenRecordset(strSql, dbOpenDynaset)
    'Determine if the requested field is multi-valued (Type is above 100.)
    bIsMultiValue = (rs(0).Type > 100)
  
    'Loop through the matching records
  
    Do While Not rs.EOF
        If bIsMultiValue Then
            'For multi-valued field, loop through the values
            Set rsMV = rs(0).value
            Do While Not rsMV.EOF
                If Not IsNull(rsMV(0)) Then
              
                    strOut = strOut & rsMV(0) & strSeparator 'Chr$(13) 'strSeparator'àí øåöéí ìäúçéì ùåøä çãùä áúåê äùãä ùîéí àú æä áî÷åí äîùúðä - âí áäîùê
                End If
                rsMV.MoveNext
            Loop
            Set rsMV = Nothing
        ElseIf Not IsNull(rs(0)) Then
      
            strOut = strOut & rs(0) & strSeparator 'Chr$(13)
        End If
        rs.MoveNext
    Loop
    rs.Close
  
    'Return the string without the trailing separator.
  
  
    lngLen = Len(strOut) ' - Len(strSeparator) 'àí ìà øåöéí ùéäéä îôøéã áñåó äùåøä îçæéøéí àú äîéðåñ
    If lngLen > 0 Then
        ConcatRelated = Left(strOut, lngLen)
    End If

Exit_Handler:

    'Clean up
    Set rsMV = Nothing
    Set rs = Nothing
    Exit Function

Err_Handler:
    MsgBox "Error " & Err.Number & ": " & Err.Description, vbExclamation, "ConcatRelated()"
    Resume Exit_Handler
End Function

וככה תקרא לו בשאילתה:
קוד:
Expr1: ConcatRelated("שדה","מטבלה","[קוד] = '" & [קוד1] & "'","",",")

הקוד הזה מכניס לשדה אחד כמה שורות עם אותו קוד לקוח.
אם יש צורך אפשר לשחק עם זה קצת שיכניס גם שדות נוספים מאותה שורה [לדוגמא, תאריך או יום].
 
נערך לאחרונה ב:

ממוו

משתמש רשום
תודה רבה
אין מילים על העזרה
רק שלא כ"כ הצלחתי להסתדר עם זה
אני מצרף פה קובץ לדוגמא אשמח אם תעשה לי בקובץ הזה את השאילתה וכך אני ידע לשחק עם זה.
אני רוצה שבקובץ יהיה לי לכל שם שורה ובה כל הפרטים שקנה עם תאריך וסכום
 

קבצים מצורפים

  • מסד נתונים4.rar
    KB 24.1 · צפיות: 18

FullTime

משתמש מקצוען
תודה רבה
אין מילים על העזרה
רק שלא כ"כ הצלחתי להסתדר עם זה
אני מצרף פה קובץ לדוגמא אשמח אם תעשה לי בקובץ הזה את השאילתה וכך אני ידע לשחק עם זה.
אני רוצה שבקובץ יהיה לי לכל שם שורה ובה כל הפרטים שקנה עם תאריך וסכום

תוריד את סיומת הTXT
 

קבצים מצורפים

  • מסד נתונים4.accdb.txt
    KB 812 · צפיות: 27

ממוו

משתמש רשום
אין מילים ממש עזרה עצומה בשבילי
מוכרח שמזהה הלקוח יהיה מספר?
כי יש לי טבלה שהמפתח שלה הוא שם ולא מספר
אני יכול להשתמש בה ג"כ באותה צורה (איך אני מכניס שדה של טקסט?)
ושוב תודה רבה רבה
 

moishy

משתמש סופר מקצוען
מנוי פרימיום
מוכרח שמזהה הלקוח יהיה מספר?
כי יש לי טבלה שהמפתח שלה הוא שם ולא מספר
בלי קשר לנושא של אשכול זה, המזהה תמיד חייב להיות מספר, רק כך ניתן להבטיח שלא יהיה מזהה החוזר על עצמו. כמו"כ הוא מועיל לשיפור הביצועים.
ניתן להוסף עמודה עם מיספור אוטומטי.
 

FullTime

משתמש מקצוען
זה לא כזה תקני, יותר נכון לעבוד עם מספר.
לצורך הענין, כדי לסנן טקסט צריך להוסיף גרש לפני ואחרי, תצטרך לשרשר את זה כך:
קוד:
"[name] = '" & [name] & "'"
 

ממוו

משתמש רשום
זה לא כזה תקני, יותר נכון לעבוד עם מספר.
לצורך הענין, כדי לסנן טקסט צריך להוסיף גרש לפני ואחרי, תצטרך לשרשר את זה כך:
קוד:
"[name] = '" & [name] & "'"
תודה רבה
עוד נקודה אחת
מכיון שאני לא כ"כ מסתדר עם שאילתה בצורה הזו
האם יש אפשרות לעשות את זה דרך פונקציה בשאילתה. (למשל בדוגמא הנ"ל את השאילתא תצוגה לעשות ע"י פונקציה)
ניסיתי לעשות את זה אבל הסתבכתי עם הסדר של הנתונים בתוך הפונקציה
תוכל לכתוב לי מה הנתונים שעלי לכתוב בפונקציה (אחרי כל פסיק)
ושוב תודה
 

ממוו

משתמש רשום
בסוף הסתדרתי עם זה (משום מה לא הצלחתי להיכנס לתצוגת עיצוב ועכשיו הסתדרתי)
תודה רבה
ועכשיו יש לי שאלה הפוכה
יש לי רשומה שיש בה 2 מספרי טלפון של הלקוח עם הנתונים שלו
ואני מעונין לקבל טבלה שבה יש רשומות שמתחילות במספר הטלפון ואח"כ את כל הפרטים כשבעצם כל לקוח נהפך ל2 רשומות שכל אחת מהם מתחילה במספר טלפון אחר שלו ואח"כ את כל הפרטים.
מה שניסיתי לעשות זה שדה שמכילה את כל הפרטים עם 2 מספרי הטלפון ומעבר שורה בין טלפון אחד עם כל הפרטים והטלפון השני עם כל הפרטים
הבעיה היא שכשאני מעתיק את הטבלה הזו (לקובץ שאני צריך) אני מקבל בתחילת כל שדה " ובסוף השדה עוד פעם " וזה מאוד משבש
(כשאני מעתיק לאקסל ללא עיצוב כערך בלבד זה כן עובד לי.)
האם יש אפשרות שפונקציה תקח את הטבלה ותכפיל אותה שלכל טלפון יהיה את כל הפרטים בשורה נפרדת?
דוגמא
הטבלה מכילה 3 שדות
05271345678,0377223344,לחם
לחלק את זה ל2 שדות
0377223344,לחם
05271345678,לחם
 

מורדי

משתמש רשום
תכין שאילתה לכל מס' טלפון (נניח שאילתה tel1 ושאילתה tel2) - מספר העמדות וסוג הנתונים בכל עמודה חייב להיות שווה.
ואח"כ תכנס בשאילתה חדשה לתצוגת sql, ותכניס את הקוד הבא:
קוד:
select * from tel1  UNION select * from tel2;
ותשמור את השאילתה בשם.
 

ממוו

משתמש רשום
תכין שאילתה לכל מס' טלפון (נניח שאילתה tel1 ושאילתה tel2) - מספר העמדות וסוג הנתונים בכל עמודה חייב להיות שווה.
ואח"כ תכנס בשאילתה חדשה לתצוגת sql, ותכניס את הקוד הבא:
קוד:
select * from tel1  UNION select * from tel2;
ותשמור את השאילתה בשם.
אין מילים
זה דבר שאני מחפש כבר כמה חודשים פיתרון בשבילו. עזרת לי מאוד
תודה רבה
 

ממוו

משתמש רשום
קרדיט ל @moishy
תוסיף את הקוד הזה למודול חדש.:
קוד:
Option Compare Database

Public Function ConcatRelated(strField As String, _
    strTable As String, _
    Optional strWhere As String, _
    Optional strOrderBy As String, _
    Optional strSeparator = ", ") As Variant
On Error GoTo Err_Handler
    'Purpose:   Generate a concatenated string of related records.
    'Return:    String variant, or Null if no matches.
    'Arguments: strField = name of field to get results from and concatenate.
    '           strTable = name of a table or query.
    '           strWhere = WHERE clause to choose the right values.
    '           strOrderBy = ORDER BY clause, for sorting the values.
    '           strSeparator = characters to use between the concatenated values.
    'Notes:     1. Use square brackets around field/table names with spaces or odd characters.
    '           2. strField can be a Multi-valued field (A2007 and later), but strOrderBy cannot.
    '           3. Nulls are omitted, zero-length strings (ZLSs) are returned as ZLSs.
    '           4. Returning more than 255 characters to a recordset triggers this Access bug:
    '               http://allenbrowne.com/bug-16.html
    Dim rs As dao.Recordset         'Related records
    Dim rsMV As dao.Recordset       'Multi-valued field recordset
    Dim strSql As String            'SQL statement
    Dim strOut As String            'Output string to concatenate to.
    Dim lngLen As Long              'Length of string.
    Dim bIsMultiValue As Boolean    'Flag if strField is a multi-valued field.
 
    'Initialize to Null
    ConcatRelated = Null
 
    'Build SQL string, and get the records.
    strSql = "SELECT " & strField & " FROM " & strTable
    If strWhere <> vbNullString Then
        strSql = strSql & " WHERE " & strWhere
    End If
 
    If strOrderBy <> vbNullString Then
        strSql = strSql & " ORDER BY " & strOrderBy
    End If
 
    Set rs = DBEngine(0)(0).OpenRecordset(strSql, dbOpenDynaset)
    'Determine if the requested field is multi-valued (Type is above 100.)
    bIsMultiValue = (rs(0).Type > 100)
 
    'Loop through the matching records
 
    Do While Not rs.EOF
        If bIsMultiValue Then
            'For multi-valued field, loop through the values
            Set rsMV = rs(0).value
            Do While Not rsMV.EOF
                If Not IsNull(rsMV(0)) Then
             
                    strOut = strOut & rsMV(0) & strSeparator 'Chr$(13) 'strSeparator'àí øåöéí ìäúçéì ùåøä çãùä áúåê äùãä ùîéí àú æä áî÷åí äîùúðä - âí áäîùê
                End If
                rsMV.MoveNext
            Loop
            Set rsMV = Nothing
        ElseIf Not IsNull(rs(0)) Then
     
            strOut = strOut & rs(0) & strSeparator 'Chr$(13)
        End If
        rs.MoveNext
    Loop
    rs.Close
 
    'Return the string without the trailing separator.
 
 
    lngLen = Len(strOut) ' - Len(strSeparator) 'àí ìà øåöéí ùéäéä îôøéã áñåó äùåøä îçæéøéí àú äîéðåñ
    If lngLen > 0 Then
        ConcatRelated = Left(strOut, lngLen)
    End If

Exit_Handler:

    'Clean up
    Set rsMV = Nothing
    Set rs = Nothing
    Exit Function

Err_Handler:
    MsgBox "Error " & Err.Number & ": " & Err.Description, vbExclamation, "ConcatRelated()"
    Resume Exit_Handler
End Function

וככה תקרא לו בשאילתה:
קוד:
Expr1: ConcatRelated("שדה","מטבלה","[קוד] = '" & [קוד1] & "'","",",")

הקוד הזה מכניס לשדה אחד כמה שורות עם אותו קוד לקוח.
אם יש צורך אפשר לשחק עם זה קצת שיכניס גם שדות נוספים מאותה שורה [לדוגמא, תאריך או יום].
עשיתי את זה ומה שיצא לי שקיבלתי את הרשימות בשורה ארוכה בשדה אחת אבל קיבלתי כמות רשומות כפי מספר הרשומות שהיו בטבלה שמכילה את כל הרשימות במקום לקבל לפי כמות הלקוחות שיש לי!
כלומר אם נניח יש לי 100 לקוחות ולכל לקוח יש בממוצע 4 פעולות שרשומות ב4 שורות
עכשיו בשאילתא מופיע לי 400 רשומות במקום 100
יש למישהו מושג למה זה קורה? (אולי זה קשור לכך שהלקוחות שלי מופיעים כטקסט ולא כמספר?)
 

FullTime

משתמש מקצוען
לא קשור לטקסט או מספר.
מה מקור השאילתה?
האם לפני שהכנסת את השדה הזה, כן היה רק 100 שורות?
 

ממוו

משתמש רשום
בסדר גמור הסתדרתי לא שמתי לב שזה קשור לטבלה שאותה הצגתי בשאילתה
 

אולי מעניין אותך גם...

הפרק היומי

הפרק היומי! כל ערב פרק תהילים חדש. הצטרפו אלינו לקריאת תהילים משותפת!


תהילים פרק קיט א'

א אַשְׁרֵי תְמִימֵי דָרֶךְ הַהֹלְכִים בְּתוֹרַת יְהוָה:ב אַשְׁרֵי נֹצְרֵי עֵדֹתָיו בְּכָל לֵב יִדְרְשׁוּהוּ:ג אַף לֹא פָעֲלוּ עַוְלָה בִּדְרָכָיו הָלָכוּ:ד אַתָּה צִוִּיתָה פִקֻּדֶיךָ לִשְׁמֹר מְאֹד:ה אַחֲלַי יִכֹּנוּ דְרָכָי לִשְׁמֹר חֻקֶּיךָ:ו אָז לֹא אֵבוֹשׁ בְּהַבִּיטִי אֶל כָּל מִצְוֹתֶיךָ:ז אוֹדְךָ בְּיֹשֶׁר לֵבָב בְּלָמְדִי מִשְׁפְּטֵי צִדְקֶךָ:ח אֶת חֻקֶּיךָ אֶשְׁמֹר אַל תַּעַזְבֵנִי עַד מְאֹד:
נקרא  30  פעמים

לוח מודעות

למעלה