برنامج إدارة مخازن مصمم بالكامل على Excel VBA — نظام إدارة مخزون متكامل يعمل بدون Access أو SQL. المقالة دي دليل حصري من البداية للنهاية يشمل أسماء كل الفورمات والموديولات والجداول والحقول المستخدمة في البرنامج.
لمن هذا البرنامج؟
هذا برنامج مخازن للمحاسبين وأصحاب المخازن والشركات الصغيرة والمشاريع المتوسطة اللي محتاجين برنامج حسابات ومخازن عملي وسريع. لو بتدور على برنامج مخازن مجاني أو برنامج مخازن Excel قابل للتعديل — ده البرنامج المناسب. نظام مخازن احترافي بيعمل كل حاجة: برنامج وارد وصادر، برنامج جرد مخازن، وتقارير HTML جاهزة للطباعة.
البنية العامة للنظام
النظام بيشتغل على مبدأ: أي نظام ناجح بيبدأ من الداتا. كل البيانات مخزنة في جداول Excel (ListObjects)، والبرمجة في VBA Excel بتنظم الوصول والعمليات.
ترتيب التشغيل
- فتح الملف →
Module_Startup ينفّذ Auto_Open
- إخفاء ورقات Excel وفتح
frmLogin
- تسجيل الدخول الناجح → فتح
frmHome (لوحة التحكم)
- المستخدم يتنقل بين الفورمات حسب الحاجة
الموديولات (Modules)
Module_Startup
الوظيفة: بدء التشغيل التلقائي عند فتح الملف.
| العنصر |
الوصف |
Auto_Open |
روتين يُستدعى تلقائياً — يخفي ورقات العمل (xlSheetVeryHidden)، يخفي نافذة Excel، ويفتح frmLogin |
Module_General — القلب النابض للنظام
كل الفورمات بتستدعي دوال من الموديول ده. لو فهمت Module_General، فهمت إزاي برنامج إدارة مخزون بيشتغل من جوه.
دوال الجداول
| الدالة |
الوظيفة |
GetLastRow(ws, col) |
إرجاع آخر صف فيه بيانات في العمود |
GetTableByName(tableName) |
البحث عن جدول ListObject بالاسم في كل الأوراق |
GetTableLastRow(tableName) |
آخر صف في الجدول |
GetWorksheetByName(sheetName) |
إرجاع ورقة العمل بالاسم |
AddRowToTable(tableName, values) |
إضافة صف للجدول |
UpdateRowInTable(tableName, rowIndex, values) |
تحديث صف |
DeleteRowFromTable(tableName, rowIndex) |
حذف صف |
دوال المنتجات
| الدالة |
الوظيفة |
GetProductByCode(productCode) |
إرجاع بيانات المنتج (مصفوفة 11 عنصر) |
GetProductByName(productName) |
البحث بالاسم |
ProductExists(productCode) |
التحقق من وجود المنتج |
دوال المخزون
| الدالة |
الوظيفة |
GetCurrentStock(productCode) |
الرصيد الحالي للصنف |
GetAverageCost(productCode) |
متوسط التكلفة (Average Cost) |
UpdateInventory(...) |
تحديث المخزون وحساب متوسط التكلفة |
دوال العملاء والموردين
| الدالة |
الوظيفة |
GetCustomerByCode(customerCode) |
بيانات العميل |
GetSupplierByCode(supplierCode) |
بيانات المورد |
CustomerExists / SupplierExists |
التحقق من الوجود |
دوال الأرقام التلقائية
| الدالة |
القيمة المعادة |
GetNewTransactionNumber() |
TRX001, TRX002… |
GetNewInvoiceInNumber() |
IN001, IN002… |
GetNewInvoiceOutNumber() |
MG01, MG02… |
GetNewStockCountNumber() |
JRD001, JRD002… |
دوال الإعدادات والتحقق
| الدالة |
الوظيفة |
GetCompanySetting(settingName) |
قراءة إعدادات الشركة (اسم، عنوان، هاتف، بريد) |
Module_Import
الوظيفة: دوال مساعدة لاستيراد المنتجات من Excel أو CSV.
| الدالة |
الوظيفة |
CleanProductCode(code) |
تنظيف رمز الصنف من المسافات والتابات وتحويله لـ UCase |
ProductExistsInTable(productCode) |
التحقق من وجود المنتج في tlbproduct |
GetProductRowIndex(productCode) |
فهرس صف المنتج |
ProductExistsInInventory(productCode) |
التحقق من وجود المنتج في tlbInventory |
GetInventoryRowIndex(productCode) |
فهرس صف المخزون |
Module_HTMLReports
الوظيفة: توليد تقارير المخازن والفواتير بصيغة HTML للطباعة والمشاركة.
| الدالة/الروتين |
الوظيفة |
GetHTMLHeader(title) |
رأس الصفحة مع CSS و RTL |
GetHTMLFooter() |
إغلاق HTML |
SaveAndOpenHTML(...) |
حفظ بترميز UTF-8 وفتح في المتصفح |
GenerateStockNowReport() |
تقرير المخزون الحالي |
GenerateInOutReport() |
تقرير الوارد والصادر |
GenerateStockCountReport(countNumber) |
تقرير الجرد الدوري |
GenerateInvoiceIn(invoiceNumber) |
فاتورة وارد |
GenerateInvoiceOut(invoiceNumber) |
فاتورة صادر |
GenerateTopSellingProducts() |
الأصناف الأكثر مبيعاً |
GenerateLowStockReport() |
الأصناف المنخفضة |
GenerateProfitLossReport() |
تقرير الأرباح والخسائر |
GenerateReorderReport() |
أصناف إعادة الطلب |
GenerateSlowMovingProductsReport() |
المنتجات الراكدة |
GenerateItemCardReport(...) |
كشف حركة صنف (كارت صنف) |
الجداول (قاعدة البيانات)
كل الجداول من نوع ListObject داخل أوراق Excel مخفية.
tlbproduct — دليل الأصناف
| العمود |
الحقل |
النوع |
| 1 |
رمز الصنف |
نص |
| 2 |
اسم الصنف |
نص |
| 3 |
الوحدة |
نص |
| 4 |
سعر الشراء |
رقم |
| 5 |
سعر البيع |
رقم |
| 6 |
تاريخ الإضافة |
تاريخ |
| 7 |
حالة المنتج (نشط/غير نشط) |
نص |
| 8 |
تاريخ آخر تحديث |
تاريخ |
| 9 |
آخر سعر شراء |
رقم |
| 10 |
آخر سعر بيع |
رقم |
| 11 |
ملاحظات |
نص |
tlbInventory — رصيد المخزون
| العمود |
الحقل |
النوع |
| 1 |
رمز الصنف |
نص |
| 2 |
اسم الصنف |
نص |
| 3 |
المخزون أول الفترة |
رقم |
| 4 |
متوسط التكلفة |
رقم |
| 5 |
الكمية الواردة |
رقم |
| 6 |
الكمية الصادرة |
رقم |
| 7 |
المخزون الحالي |
رقم |
| 8 |
قيمة المخزون |
رقم |
| 9 |
آخر حركة |
تاريخ |
| 10 |
حد التنبيه |
رقم |
| 11 |
الحالة (منخفض/كافي/زائد) |
نص |
| 12 |
Average Cost (إن وجد) |
رقم |
tlbTransaction — حركات الوارد والصادر
| العمود |
الحقل |
النوع |
| 1 |
رقم الحركة |
نص (TRX001…) |
| 2 |
التاريخ |
تاريخ |
| 3 |
نوع الحركة (وارد/صادر) |
نص |
| 4 |
رمز الصنف |
نص |
| 5 |
اسم الصنف |
نص |
| 6 |
الكمية |
رقم |
| 7 |
سعر الوحدة |
رقم |
| 8 |
الإجمالي |
رقم |
| 9 |
(احتياطي) |
— |
| 10 |
العميل/المورد |
نص |
| 11 |
رقم الفاتورة |
نص (IN001, MG01…) |
| 12 |
تم بواسطة |
نص |
| 13 |
ملاحظات |
نص |
tlbUsers — المستخدمون
| العمود |
الحقل |
| 1 |
اسم المستخدم |
| 2 |
كلمة المرور |
tlbcustomer — العملاء
| العمود |
الحقل |
| 1 |
كود العميل |
| 2 |
اسم العميل |
| 3 |
الهاتف |
| 4 |
البريد |
| 5 |
العنوان |
| 6 |
ملاحظات |
tlbsupplier — الموردون
| العمود |
الحقل |
| 1 |
كود المورد |
| 2 |
اسم المورد |
| 3 |
الهاتف |
| 4 |
البريد |
| 5 |
العنوان |
| 6 |
ملاحظات |
tlbStockCountHeader — رأس الجرد الدوري
| العمود |
الحقل |
| 1 |
رقم الجرد (JRD001…) |
| 2 |
تاريخ الجرد |
| 3 |
عدد الأصناف |
| 4 |
إجمالي العجز |
| 5 |
إجمالي الزيادة |
tlbStockCount — تفاصيل الجرد
| العمود |
الحقل |
| 1 |
رقم الجرد |
| 2 |
(احتياطي) |
| 3 |
رمز الصنف |
| 4 |
اسم الصنف |
| 5 |
الرصيد الدفتري |
| 6 |
الرصيد الفعلي |
| 7 |
الفرق |
| 8 |
نوع الفرق (عجز/زيادة/مطابق) |
الفورمات (UserForms)
frmLogin — تسجيل الدخول
الوظيفة: حماية النظام — مفيش دخول بدون تحقق.
| العنصر |
النوع |
الوظيفة |
| txtUsername |
TextBox |
اسم المستخدم |
| txtPassword |
TextBox |
كلمة المرور (PasswordChar = “*”) |
| cmdLogin |
CommandButton |
تنفيذ تسجيل الدخول |
| cmdOut |
CommandButton |
الخروج من النظام وإغلاق Excel |
الأحداث: UserForm_Initialize، cmdLogin_Click، cmdOut_Click، txtPassword_KeyDown (Enter ينفّذ cmdLogin)
frmHome — لوحة التحكم (داشبورد Excel)
الوظيفة: نقطة البداية — إحصائيات وأزرار التنقل.
| العنصر |
النوع |
الوظيفة |
| Label42 |
Label |
إجمالي قيمة المخزون |
| Label41 |
Label |
عدد الأصناف المنخفضة |
| lblTotalProductNow |
Label |
إجمالي المنتجات |
| Label43 |
Label |
عدد حركات الوارد |
| Label44 |
Label |
عدد حركات الصادر |
| ListBoxfrmHome |
ListBox |
آخر 50 حركة (8 أعمدة) |
| btnfrmproduct |
CommandButton |
فتح فورم المنتجات |
| btnWared |
CommandButton |
فتح فورم الوارد |
| btnSader |
CommandButton |
فتح فورم الصادر |
| btnReport |
CommandButton |
فتح فورم التقارير |
| btnCard |
CommandButton |
فتح كارت الصنف |
| btnRefresh |
CommandButton |
تحديث لوحة التحكم |
| btnExcel |
CommandButton |
فتح ملف Excel |
| btnOut |
CommandButton |
تسجيل الخروج |
frmWared — فورم حركة الوارد (فاتورة وارد)
الوظيفة: تسجيل حركات الدخول للمخزن — شراء، مرتجع، رصيد افتتاحي.
| العنصر |
النوع |
الوظيفة |
| comProductCode |
ComboBox |
اختيار رمز الصنف |
| comProductName |
ComboBox |
اختيار اسم الصنف |
| comUnit |
ComboBox |
الوحدة (تعبئة تلقائية) |
| txtqtyIN |
TextBox |
الكمية |
| txtPurchasePrice |
TextBox |
سعر الشراء |
| txtSalePrice |
TextBox |
سعر البيع |
| txtdateIn |
TextBox |
تاريخ الفاتورة |
| txtInvoiceNum |
TextBox |
رقم الفاتورة (IN001…) |
| cobSupplierName |
ComboBox |
اسم المورد |
| txtcaerteBy |
TextBox |
تم بواسطة |
| txtNotes |
TextBox |
ملاحظات |
| lbQtyNow |
Label |
الرصيد الحالي |
| lblTotalPriceStock |
Label |
إجمالي السعر |
| ListBox1 |
ListBox |
قائمة الفواتير المسجلة |
| ListBox2 |
ListBox |
عربة الأصناف (رمز، اسم، كمية، سعر، إجمالي) |
| cmdAddtoCar |
CommandButton |
إضافة للعربة |
| btnfrmsupplier |
CommandButton |
إضافة مورد جديد |
frmSader — فورم حركة الصادر (فاتورة صادر)
الوظيفة: تسجيل المبيعات وحركات الخروج — مع تحقق من عدم تجاوز الرصيد.
| العنصر |
النوع |
الوظيفة |
| comProductCodeout |
ComboBox |
رمز الصنف |
| comProductNameOut |
ComboBox |
اسم الصنف |
| comunitsOut |
ComboBox |
الوحدة |
| txtSalepriceOut |
TextBox |
سعر البيع |
| lblQtyStock |
Label |
الرصيد المتاح |
| comCustomrName |
ComboBox |
اسم العميل |
| txtInvoiceNumOut |
TextBox |
رقم الفاتورة (MG01…) |
frmProduct — فورم إدارة المنتجات
الوظيفة: عرض دليل الأصناف مع الرصيد الحالي، إضافة، تعديل، حذف، استيراد، تصدير.
| العنصر |
النوع |
الوظيفة |
| ListBox1 |
ListBox |
قائمة المنتجات |
| cmdAddNew |
CommandButton |
إضافة منتج (يفتح frmItimeData) |
| cmdEdit |
CommandButton |
تعديل منتج |
| cmdDelete |
CommandButton |
حذف منتج |
| cmdImport |
CommandButton |
استيراد (يفتح frmImport) |
| cmdRefresh |
CommandButton |
تحديث القائمة |
frmItimeData — فورم إضافة/تعديل منتج
الوظيفة: بيانات الصنف — يستخدم للإضافة والتعديل (isEditMode يفرّق بينهم).
| العنصر |
النوع |
الوظيفة |
| txtProductCode |
TextBox |
رمز الصنف |
| txtProductName |
TextBox |
اسم الصنف |
| txtUnit |
TextBox |
الوحدة |
| txtPurchasePrice |
TextBox |
سعر الشراء |
| txtSalePrice |
TextBox |
سعر البيع |
| txtNotes |
TextBox |
ملاحظات |
| btnAddSave |
CommandButton |
حفظ |
frmItemCard — فورم كشف حركة صنف (كارت صنف)
الوظيفة: عرض حركات الوارد والصادر لصنف في فترة معيّنة — رصيد أول، وارد، صادر، رصيد نهائي.
| العنصر |
النوع |
الوظيفة |
| cmbItem |
ComboBox |
اختيار الصنف |
| txtFromDate |
TextBox |
من تاريخ |
| txtToDate |
TextBox |
إلى تاريخ |
| lblItemName |
Label |
اسم الصنف |
| ListboxItemTrans |
ListBox |
الحركات |
| cmdSearch |
CommandButton |
تنفيذ البحث |
frmJard — فورم الجرد الدوري
الوظيفة: مقارنة الرصيد الدفتري بالرصيد الفعلي — عجز، زيادة، مطابقة — واعتماد الجرد لتوليد حركات تلقائية.
| العنصر |
النوع |
الوظيفة |
| txtCountNo |
TextBox |
رقم الجرد (JRD001…) |
| txtCountDate |
TextBox |
تاريخ الجرد |
| ListBox1 |
ListBox |
الأصناف |
| lblItemName |
Label |
اسم الصنف المحدد |
| txtActualQty |
TextBox |
الرصيد الفعلي (بعد العد) |
| btnload |
CommandButton |
تحميل الأصناف |
| btnUpdateQty |
CommandButton |
تحديث الرصيد الفعلي للصنف |
frmImport — فورم استيراد المنتجات
الوظيفة: استيراد منتجات من ملف Excel أو CSV — معاينة، تحقق، خيارات (تحديث موجود، تخطي مكرر، إضافة جديد).
| العنصر |
النوع |
الوظيفة |
| txtFilePath |
TextBox |
مسار الملف |
| cmdBrowse |
CommandButton |
استعراض ملف |
| cmdLoadPreview |
CommandButton |
تحميل معاينة |
| ListBox1 |
ListBox |
معاينة البيانات |
| chkUpdateExisting |
CheckBox |
تحديث المنتجات الموجودة |
| chkSkipDuplicates |
CheckBox |
تخطي المكررات |
| optAddNew |
OptionButton |
إضافة منتجات جديدة فقط |
| cmdImport |
CommandButton |
تنفيذ الاستيراد |
| cmdImportupdate |
CommandButton |
استيراد مع تحديث |
الأعمدة المتوقعة في ملف الاستيراد: A=رمز، B=اسم، C=وحدة، D=سعر شراء، E=سعر بيع، F=كمية، G=ملاحظات
frmReport — فورم التقارير
الوظيفة: أزرار لكل تقرير — يستدعي دوال من Module_HTMLReports.
| الزر |
التقرير |
| cmdReportStockNow |
المخزون الحالي |
| cmdReportInOut |
الوارد والصادر |
| cmdJard |
الجرد الدوري |
| cmdHtmlWinerProdect |
الأصناف الأكثر مبيعاً |
| cmdHtmlProdectLow |
الأصناف المنخفضة |
| cmdhtmlOut |
حركة الصادر فقط |
| cmdhtmlIn |
حركة الوارد فقط |
| cmdHTMLStock |
قيمة المخزون |
| cmdProfitLost |
الأرباح والخسائر |
| cmdAgen |
أصناف إعادة الطلب |
| btnRakeed |
المنتجات الراكدة |
frmCustomer — فورم إضافة عميل
الوظيفة: إضافة عميل جديد من داخل فورم الصادر.
| العنصر |
النوع |
الحقل |
| txtCodCustomer |
TextBox |
كود العميل |
| txtCustomerName |
TextBox |
اسم العميل |
| txtphone |
TextBox |
الهاتف |
| txtEmail |
TextBox |
البريد |
| txtadress |
TextBox |
العنوان |
| txtNot |
TextBox |
ملاحظات |
| btnAddSave |
CommandButton |
حفظ في tlbcustomer |
frmsupplier — فورم إضافة مورد
الوظيفة: إضافة مورد جديد من داخل فورم الوارد.
| العنصر |
النوع |
الحقل |
| txtCodsup |
TextBox |
كود المورد |
| txtSupName |
TextBox |
اسم المورد |
| txtphone |
TextBox |
الهاتف |
| txtEmail |
TextBox |
البريد |
| txtadress |
TextBox |
العنوان |
| txtNot |
TextBox |
ملاحظات |
| btnAddSave |
CommandButton |
حفظ في tlbsupplier |
كيفية تصميم برنامج مخازن باستخدام Excel
البرنامج بيوضّح إن تصميم برنامج مخازن كامل على Excel ممكن بدون قواعد بيانات خارجية. الفكرة الأساسية:
- الجداول كقاعدة بيانات — ListObjects مع أسماء ثابتة
- دوال عامة للمنطق — Module_General قلب النظام
- الفورمات للواجهة فقط — تستدعي الدوال وتعرَض البيانات
- تحديث المخزون مركزي — UpdateInventory يتنفّذ من كل مكان يحدث حركة
مميزات برنامج إدارة المخازن Excel
- برنامج مخازن بدون Access وبدون SQL — يعمل على Excel فقط
- برنامج وارد وصادر Excel VBA مع عربة وتسجيل كامل
- برنامج جرد مخازن Excel مع اعتماد وتوليد حركات تلقائية
- تقارير HTML جاهزة للطباعة — فواتير، كارت صنف، تقارير مخزون
- متوسط تكلفة تلقائي (Average Cost)
- استيراد من Excel/CSV مع خيارات مرنة
- UserForm VBA احترافي — أتمتة Excel كاملة
هل Excel مناسب لإدارة المخزون؟
للشركات الصغيرة والمشاريع المتوسطة — نعم. برنامج إدارة مخزون للشركات الصغيرة بيقدر يلبّي الحاجة بدون تعقيد. لو البيانات تكبر جداً (ملايين الحركات)، الأفضل الانتقال لـ ERP أو قاعدة بيانات. لكن كبداية أو لمشروع محدود — أفضل برنامج مخازن Excel ممكن تبني عليه وتطوّره.
تحميل برنامج إدارة مخازن Excel VBA
البرنامج جزء من سلسلة تعليمية — الملف الرئيسي Stock-Gafar-Pro – Import-V2.xlsb. لو حابب تحميل برنامج إدارة مخازن Excel VBA كامل، تابع القناة أو المصدر اللي بيقدّم السلسلة.
شرح أكواد VBA المستخدمة في البرنامج
الأكواد في الموديولات والفورمات بتتبع مبدأ: الكود مش صعب — الصعب إنك تفهم المشكلة. كل دالة ليها دور واضح، والتحقق من البيانات (Validation) موجود قبل الحفظ. لو حابب شرح أكواد VBA لبرنامج مخازن تفصيلي، راجع سكربت الفيديو الرابع أو الملف سكربت_الفيديو_الرابع_التعليمي.md.
الخاتمة
برنامج مخازن Excel ده بيوضّح إزاي نظام إدارة مخزون احترافي يتبنى بالكامل على VBA Excel. من تسجيل الدخول، لحركات الوارد والصادر، للجرد الدوري، لاستيراد المنتجات، لتقارير المخازن — كل حاجة في مكان واحد. برنامج مخازن عملي قابل للتعديل والتوسّع، مناسب للمحاسبين وأصحاب المخازن والشركات الصغيرة. نظام مخازن احترافي باستخدام Excel بدون الحاجة لبرامج معقدة أو تكاليف إضافية.