تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
إخراج رقم تسلسلي لفواتير أو طلبات
#1
السلام عليكم ورحمة الله

بقدر ما تعلمت من منتدى الفيجوال بيسك و استمراراً بهذا المنتدى الجديد، بفضل الله ثم بفضل الزملاء و الأعضاء فيه لما وصلت إلى ما أنا عليه اليوم في البرمجة. و أحببت أن أفيد كما استفدت، و هذا ما علمنا إياه رسولنا الأعظم صلى الله عليه و سلم حينما قال: إذا مات ابن آدم انقطع عمله إلا من ثلاث: صدقة جارية، أو علم ينتفع به، أو ولد صالح يدعو له. و لقد تم تعديل المشاركة في هذا المنتدى و ذلك بعد التجربة و معرفة الأخطاء و حلها خاصة في عمل أرقام فواتير تشمل أرقام و أحرف.

درسي الأول و أتمنى أن لا يكون الأخير هو فكرة خطرت لي و هو عن كيفية عمل رقم متسلسل مع تاريخ و مع أحرف ليكون رقم غير متكرر تستطيع أن تضعه كمفتاح رئيسي “Primary Key” لسجل في قاعدة البيانات الخاصة لفاتورة أو لطلب و ذلك بالاعتماد على ما يتم إدخاله على قاعدة البيانات في يوم الإدخال.

ممكن هذه الفكرة لا يستفيد منها المبرمجين الكبار لدينا في المنتدى، و لكنها أكيد ستفيد المتلهفين لتعلم البرمجة. و الدرس مفتوح للاستفادة من خبرات الأساتذة الكبار في المنتدى.

نبدأ بعد "بسم الله الرحمن الرحيم"
و ما توفيقي إلا بالله، إن أصبت فهو من الله و إن أخطأت فهو من نفسي.

أولاً ننشئ جدول في برنامج الأكسس ونسميه Billing و هذا جدول الفواتير وهو كمثال طبعاً ليساعدنا في الشرح و حقوله كالتالي:
• Bill_no
• Prod_id
• Prod_name
• quantity
• amount
• bill_date

ثانياً ننشأ برنامج يحتوي على خمسة صناديق نصوص TextBox و نقوم بتسميتهم كالتالي:
• لرقم الفاتورة و هو الأساس في هذا الدرس نقوم بتسميته tb_billno.
• لرقم الباركود للبضاعة tb_barcode
• لاسم البضاعة tb_name
• للكمية tb_qnt
• للقيمة tb_amt

و أيضاً نقوم بإضافة زر للإضافة فاتورة bt_add.
و داخل صفحة الأكواد نقوم بتعريف billno كمتغير عشري Decimal، و داتاست ds1، و متغير نصي String اسمه sql1 و billno_str

هناك طريقتان لعمل رقم الفاتورة تعتمد على إذا كانت هناك الفاتورة عبارة عن رقم متسلسل فقط أو رقم مع أحرف.

الطريقة الأولى: التسلسل الرقمي

سأعتمد هنا على التسلسل الرقمي مع التاريخ
نقوم بعمل Private Sub و اسمه AutoBillNum و نكتب الكود التالي.

PHP كود :
Private Sub AutoBillNum()
billno CInt(Now.Year)
        If 
CInt(Now.Month) < 10 Then
            billno 
billno CInt(Now.Month)
        Else
            
billno &= CInt(Now.Month)
        
End If
        If 
CInt(Now.Day) < 10 Then
            billno 
billno CInt(Now.Day)
        Else
            
billno &= CInt(Now.Day)
        
End If

        
billno &= 100
        billno 
-= 99

        billno 
billno

        sql1 
"select * from billing where bill_no =" billno
        da 
= New OleDbDataAdapter(sql1conn)
        
ds1.Clear()
        
da.Fill(ds1" billing ")
        If 
BindingContext(ds1"bills").Count 0 Then
            
Exit Sub
        
ElseIf BindingContext(ds1"bills").Count 0 Then
            sql1 
"select max(bill_no) as bill_no from bills"  where comp_date #" & Now.Date & "#"
            
da = New OleDbDataAdapter(sql1conn)
            
ds1.Clear()
            
da.Fill(ds1"bills")
            
billno ds1.Tables("bills").Rows(0).Item("bill_no")
            
billno += 1
        End 
If
        
End Sub 

شرح الكود:
billno = CInt(Now.Year)
If CInt(Now.Month) < 10 Then
billno = billno & 0 & CInt(Now.Month)
Else
billno &= CInt(Now.Month)
End If
If CInt(Now.Day) < 10 Then
billno = billno & 0 & CInt(Now.Day)
Else
billno &= CInt(Now.Day)
End If

يقوم المتغير بأخذ قيمة السنة و من ثم قيمة الشهر و إذا قيمة الشهر أقل من عشرة يقوم بأخذه مع الصفر و نفس العملية لرقم اليوم. وهذه الخطوة حتى يتم الحصول على نفس طول الرقم في أي يوم من أيام الشهر و السنة و يكون الرقم هو نفسه التاريخ و لكن بالعكس.
20110101 و 20111231

billno &= 100
billno -= 99
المتغير هنا يقوم بإضافة 100 و من ثم طرحها و ذلك لعمل تسلسل و التصفير بعد التاريخ فيكون كالتالي:
20111204000

billno = 1 & billno
هذه الخطوة اختيارية و ذلك إذا أردت أن تعمل فاتورة خاصة بالبيع و أخرى للشراء و ذلك بإضافة 1 قبل الرقم المتسلسل و هو يفيد البيع و 2 للشراء.
120111204000 و 220111204000

sql1 = "select * from billing where bill_no =" & billno
da = New OleDbDataAdapter(sql1, conn)
ds1.Clear()
da.Fill(ds1, " billing ")
هنا يتم تحميل جدول الفواتير على داتاست، هذه الخطوة حتى يتم مقارنة في الخطوة التالية رقم الفاتورة الجديدة مع الموجودة مسبقاً أو حتى نبدأ بتسلسل الفواتير في اليوم الجديد.

If BindingContext(ds1, "bills").Count = 0 Then
Exit Sub
هنا يقوم بمقارنة الفاتورة رقم المتسلسل لها صفر مع تاريخ اليوم الحالي إذا كان موجود أم لا، فإذا لم يكن موجوداً يتم تثبيت هذه القيمة لأول فاتورة في الجدول لهذا اليوم و من ثم يبدأ التسلسل للفواتير اللاحقة.

ElseIf BindingContext(ds1, "bills").Count > 0 Then
sql1 = "select max(bill_no) as bill_no from bills" ' where comp_date = #" & Now.Date & "#"
da = New OleDbDataAdapter(sql1, conn)
ds1.Clear()
da.Fill(ds1, "bills")
billno = ds1.Tables("bills").Rows(0).Item("bill_no")
billno += 1
End If
في هذه الخطوة يتأكد أن هناك فاتورة تبدأ من صفر في هذا التاريخ، و نقوم هنا بتحميل أكبر قيمة للفاتورة و جمع القيمة مع 1، و من هنا يكون متسلسل، الفكرة هي رقم الفاتورة هو عبارة عن رقم عشري من السنة و التسلسل فبهذا يكون كل يوم أكبر من اليوم الذي قبله.

في حدث Click لزر الإضافة

PHP كود :
Try
AutoBillNum()
With savcom
                
.Connection conn
                
.CommandType CommandType.Text
                
.CommandText "insert into Billing (bill_no, prod_id, prod_name, quantity, amount, bill_date) values(?, ?, ?, ?, ?, ?)"
                
.Parameters.Clear()
                .
Parameters.AddWithValue("@billno"OleDbType.Decimal).Value billno
                
.Parameters.AddWithValue("@pid"OleDbType.VarChar).Value tb_barcode.Text.Trim
                
.Parameters.AddWithValue("@pname"OleDbType.VarChar).Value tb_name.Text.Trim
                
.Parameters.AddWithValue("@qnt"OleDbType.Integer).Value Val(tb_qnt.Text.Trim)
                .
Parameters.AddWithValue("@amt"OleDbType.Double).Value Val(tb_amt.Text.Trim)
                .
Parameters.AddWithValue("@bdate"OleDbType.Date).Value Format(“MM/dd/yyyy”Now.Date)
            
End With
            
If conn.State ConnectionState.Open Then conn.Close()
            
conn.Open()
            
savcom.ExecuteNonQuery()
            
conn.Close()
            
MsgBox("The new bill added successfully"MsgBoxStyle.Information"Generating Purchasing Bill")
        Catch 
ex As Exception
            MsgBox
(ex.Message)
        
End Try 

أما الطريقة الثانية فهي التسلسل الرقمي مع وجود أحرف.

PHP كود :
Private Sub AutoBillNum()
        
Dim sq1sq2 As String
        Dim ds1
ds2 As New DataSet

        billno 
CInt(Now.Year)

        If 
CInt(Now.Month) < 10 Then
            billno 
billno CInt(Now.Month)
        Else
            
billno &= CInt(Now.Month)
        
End If

    If 
CInt(Now.Day) < 10 Then
            billno 
billno CInt(Now.Day)
        Else
            
billno &= CInt(Now.Day)
        
End If

        
billno_str CStr(billno)

        
billno &= 1000
        billno 
-= 999

        ds1
.Clear()
        
sq1 "select bill_no from billing where bill_no like '%" billno_str "%'"
        
da = New OleDbDataAdapter(sq1conn)
        
da.Fill(ds1"billing")
        If 
ds1.Tables("billing").Rows.Count 0 Then
            billno 
+= ds1.Tables("billing").Rows.Count
            billno_str 
"Bill" billno

            
For 0 To ds1.Tables("billing").Rows.Count 1
                ds2
.Clear()
                
sq2 "select bill_no from billing where bill_no = '" billno_str "'"
                
da = New OleDbDataAdapter(sq2conn)
                
da.Fill(ds2"billing")

                If 
ds2.Tables("billing").Rows.Count 0 Then
                    billno 
+= 1
                    billno_str 
"Bill" billno
                
Else
                    Exit For
                
End If
            
Next
        
Else
            
billno_str "Bill" billno
        End 
If
 
End Sub 


billno = CInt(Now.Year)

If CInt(Now.Month) < 10 Then
billno = billno & 0 & CInt(Now.Month)
Else
billno &= CInt(Now.Month)
End If

If CInt(Now.Day) < 10 Then
billno = billno & 0 & CInt(Now.Day)
Else
billno &= CInt(Now.Day)
End If

billno &= 100
billno -= 99
جميع ما سبق تم إيضاحه.

sql1 = "select distinct (bill_no) from billing where bill_date = #" & Format("MM/dd/yyyy", Now.Date) & "#"
da = New OleDbDataAdapter(sql1, conn)
ds1.Clear()
da.Fill(ds1, "billing")

في هذه الخطوة نقوم باستدعاء أرقام الفواتير لتاريخ اليوم الحالي و بدون تكرار.

billno += BindingContext(ds1, "billing").Count
billno_str = "Bill" & billno
أخيراً نقوم بزيادة رقم الفاتورة المبدئية لهذا اليوم برقم عدد الفواتير الموجودة لنفس اليوم، و من ثم نضيف عليها الأحرف المطلوبة.
ملاحظة: في هذه الحالة يجب أن يكون نوع المتغير في حقل رقم الفاتورة في قاعدة البيانات هو String أو VarChar

الرجاء إن كان هذا الموضوع قد أفادكم، فلا تنسوني من صالح الدعاء.

الموضوع مفتوح للمشاركة و المناقشة، فإذا كان هناك خطأ أو أي شيء قد غفلت عنه فأرجوا الإفادة.
و الحمد الله و لله الفضل و المنة.
الرد }}}}
تم الشكر بواسطة: العزابي , العزابي
#2
ممكن اخوي البرنامج التجريبي للكود
الرد }}}}
تم الشكر بواسطة:
#3
في أقرب وقت إن شاء الله
الرد }}}}
تم الشكر بواسطة:
#4
بارك الله فيك شرح قيم
الرد }}}}
تم الشكر بواسطة:
#5
شكرا .
(( نحن قوم أعزنا الله بالإسلام فمهما ابتغينا العزة بغيره أذلنا الله )) .. 











الرد }}}}
تم الشكر بواسطة:


التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم