معادن · الصيانة الميكانيكية PAP · حماية HEMAYA

حماية: دمج الملفات والداشبورد اليومي

ملفات حماية توصلك من أكثر من مكان وبأشكال مختلفة. هذا الدليل يعلمك تحولينها لجدول واحد ثابت الشكل (بالإكسل أولًا عشان تفهمين، وبـ Power Query عشان يشتغل كل يوم بضغطة)، وبعدين يشرح الداشبورد اليومي بطاقة بطاقة: من وين كل رقم، وكيف ينحسب، وليش.

قبل ما تبدين

الفكرة في سطر

الداشبورد ما يقرأ الملفات اللي توصلك أبدًا. يقرأ جدول واحد اسمه tblHEMAYA_Log شكله ثابت. كل ملف جديد يمر بخطوة ترجمة تحوله لهذا الشكل. لو تغير المصدر بكرة، تعدلين الترجمة بس، والداشبورد ما يحس.

ملفات المصدرتصدير نظام حماية، وملف المقاول، وأي ملف ثالث. كل واحد بشكله.
الترجمةإعادة تسمية الأعمدة، وتصحيح القيم، وإضافة الناقص فاضي.
الجدول القياسيtblHEMAYA_Log في ملف HEMAYA_Merged.xlsx، مع قسم كل شخص.
الداشبوردPower BI يقرأ الجدول ويحدث كل يوم.
القالب الجاهز05_Daily_Meeting\3_Output\HEMAYA_Merge_Template.xlsx: فيه مثال لمصدرين مختلفين، وجدول الترجمة، والدمج بمعادلات الإكسل، وكود Power Query جاهز للنسخ. افتحيه جنب هذا الدليل.

الخطوة 1

الشكل القياسي: 19 عمود ما تتغير

هذي أعمدة tblHEMAYA_Log اللي يقرأها الداشبورد. لا تغيرين اسم ولا ترتيب. إذا مصدر ما عنده عمود، يبقى فاضي.

العمودالنوعوش يعنييظهر في الداشبورد اليومي؟
IDنصرقم الملاحظة، لازم يكون فريدمفتاح العد
Reportedتاريختاريخ الرصدهذا الشهر
Area · Locationنصالمنطقة (Train A/B/C، Common Area، Cooling Tower) والمكان بالضبطنعم: وين
Type · Category · Severityنصنوع الملاحظة وتصنيفها وشدتهانعم: وش نوعها
What happenedنصالوصفنعم
Corrective action (how closed)نصخطوات الإصلاحنعم: كيف تنقفل
Raised byنصمين رفعهانعم: كل موظف كم رفع
Ownerنصمين مسند له الإغلاقنعم: المسند للميكانيكال
Target date · Closed date · Statusتاريخ / نصالهدف، الإغلاق الفعلي، الحالة (Open، In progress، Closed)مفتوح أو متأخر
Sourceنصمن أي ملف جات (System، Contractor)للتدقيق

الجدول الثاني: People

الداشبورد ما يعرف إن "Foreman B" ميكانيكي. يعرفه من جدول tblHEMAYA_People: الاسم، والقسم. كل اسم يظهر في Raised by أو Owner لازم يكون فيه، وإلا قسمه يطلع Other وما ينحسب للفريق.

NameDepartmentRole
Foreman AMechanicalForeman
Mechanical supervisorMechanicalSupervisor
RawabiMechanicalData analyst
HSE officerHSEOfficer
Supervisor CommonOperationsSupervisor

ليش ما نكتب القسم في كل سطر ملاحظة؟ لأن الاسم يتكرر مئات المرات والقسم يتغير مرة بالسنة. مكان واحد للمعلومة، مثل ماستر الموظفين.

الخطوة 2

بالإكسل أولًا: XLOOKUP و VSTACK

هذي الطريقة عشان تفهمين وتتحققين. الطريقة اليومية هي Power Query في الخطوة 3. افتحي شيت Merged_Excel في القالب وشوفي المعادلات وهي شغالة.

أ. ترجمة القيم بـ XLOOKUP

المقاول يكتب Train-B وإحنا نكتب Train B. جدول tblValueFix فيه From و To، والمعادلة:

=XLOOKUP([@Section], tblValueFix[From], tblValueFix[To], [@Section])

آخر وسيطة هي "إذا ما لقيت": ترجّع القيمة نفسها. كذا القيم الصحيحة أصلًا تمر بدون تغيير.

ب. القسم من People بـ XLOOKUP

=XLOOKUP([@Owner], tblPeople[Name], tblPeople[Department], "Other")

نفس الفكرة: الاسم ← القسم، والافتراضي Other عشان تلاحظين الأسماء الناقصة بسرعة (فلتري على Other).

ج. لزق الملفين تحت بعض بـ VSTACK (Excel 365)

كل مصدر تختارين أعمدته بالترتيب القياسي بـ HSTACK، وبعدين VSTACK يحطهم تحت بعض:

=VSTACK(
   HSTACK(tblSrcSystem[ID], tblSrcSystem[Reported], tblSrcSystem[Area], ...),
   HSTACK(tblSrcContractor[Ref No], DATEVALUE(tblSrcContractor[Date]),
          XLOOKUP(tblSrcContractor[Section], tblValueFix[From], tblValueFix[To], tblSrcContractor[Section]), ...)
)
  • DATEVALUE لأن المقاول يكتب التاريخ نص "10/09/2026"، والداشبورد يبغاه تاريخ.
  • المعادلة تنسكب (spill) لحالها بعدد الصفوف. لا تكتبين شي تحتها.
  • الأعمدة الناقصة عند المقاول (Equipment، Root cause) تحط مكانها "".
ليش ما نعتمد هذي الطريقة للداشبورد؟ لأن Power BI يقرأ الجداول (Ctrl+T) مو المعادلات المنسكبة، والمعادلة تنكسر لو تغير ترتيب عمود في ملف المصدر. Power Query يسوي نفس الشي بشكل يتحمل التغيير ويعيد التشغيل بـ Refresh.

الخطوة 3

الطريقة المعتمدة: Power Query

الهدف: ملف اسمه HEMAYA_Merged.xlsx فيه شيت People وشيت HEMAYA_Log (جدول tblHEMAYA_Log) يتعبى لحاله من الملفين.

  1. جهزي مجلد ثابت وأسماء ثابتة
    مثلًا OneDrive\HEMAYA\ وفيه HEMAYA_System_Export.xlsx و HEMAYA_Contractor.xlsx. كل مرة يوصلك ملف، احفظيه فوق القديم بنفس الاسم. ليش: Power Query يبحث بالاسم، ولو تغير الاسم ينكسر.
  2. سوي ملف HEMAYA_Merged.xlsx وفيه شيت People
    انسخي جدول People من القالب (Ctrl+T واسمه tblPeople).
  3. Data ← Get Data ← From Other Sources ← Blank Query ← Advanced Editor
    الصقي الكود اللي تحت (موجود كامل في شيت PowerQuery_M بالقالب)، وغيري FolderPath بس.
  4. سمّي الاستعلام HEMAYA_Log ← Close & Load To ← Table ← شيت جديد
    الجدول اللي يطلع اسمه تلقائيًا HEMAYA_Log. غيريه إلى tblHEMAYA_Log من Table Design. ليش: الداشبورد يدور على هذا الاسم بالضبط.
  5. تحققي
    فلتري عمود Owner dept على Other: كل اسم يطلع هنا ناقص في People. أضيفيه وRefresh.

الكود، خطوة خطوة

// المصدر 1: تصدير النظام (أعمدته أصلاً قياسية)
Sys1 = Excel.Workbook(File.Contents(FolderPath & "HEMAYA_System_Export.xlsx"), null, true){[Item="tblSrcSystem", Kind="Table"]}[Data],
Sys2 = Table.AddColumn(Sys1, "Source", each "System", type text),

// المصدر 2: المقاول. الترجمة = إعادة تسمية الأعمدة (نفس Column_Map في القالب)
Con2 = Table.RenameColumns(Con1, {{"Ref No","ID"}, {"Date","Reported"}, {"Section","Area"}, {"Place","Location"},
        {"Observation","What happened"}, {"Obs Type","Type"}, {"Hazard","Category"}, {"Risk","Severity"},
        {"Reported By","Raised by"}, {"Assigned To","Owner"}, {"Action Taken","Corrective action (how closed)"},
        {"Due","Target date"}, {"Closed On","Closed date"}, {"Stage","Status"}}),
Con4 = Table.ReplaceValue(Con3, "Train-", "Train ", Replacer.ReplaceText, {"Area"}),   // تصحيح القيم

// الشكل القياسي: دالة صغيرة تضيف الأعمدة الناقصة فاضية وترتب الأعمدة
Std  = {"ID","Reported","Area","Location","Equipment","Type","Category","Severity","What happened",
        "Root cause (why)","Immediate action","Corrective action (how closed)","Raised by","Owner",
        "Target date","Closed date","Status","Verified by","Source"},
Fill = (t as table) as table =>
        let missing = List.Difference(Std, Table.ColumnNames(t)),
            added   = List.Accumulate(missing, t, (acc, c) => Table.AddColumn(acc, c, each null, type text))
        in  Table.SelectColumns(added, Std),

// الدمج تحت بعض = Append
All   = Table.Combine({Fill(Sys2), Fill(Con8)}),
Typed = Table.TransformColumnTypes(All, {{"Reported", type date}, {"Target date", type date}, {"Closed date", type date}}, "en-GB"),

// القسم من People = Merge (نفس XLOOKUP)
J1 = Table.NestedJoin(Typed, {"Owner"}, People0, {"Name"}, "OP", JoinKind.LeftOuter),
J2 = Table.ExpandTableColumn(J1, "OP", {"Department"}, {"Owner dept"}),
J3 = Table.NestedJoin(J2, {"Raised by"}, People0, {"Name"}, "RP", JoinKind.LeftOuter),
J4 = Table.ExpandTableColumn(J3, "RP", {"Department"}, {"Raised dept"}),
Final = Table.ReplaceValue(J4, null, "Other", Replacer.ReplaceValue, {"Owner dept", "Raised dept"})
في الإكسلفي Power Queryالفرق
XLOOKUPMerge Queries (NestedJoin) ثم ExpandMerge يجيب أكثر من عمود مرة وحدة، ويفرق بين الكبيرة والصغيرة
VSTACKAppend Queries (Table.Combine)Combine يطابق بالاسم مو بالترتيب، فلازم الأسماء متطابقة
إعادة تسمية العمود يدويًاTable.RenameColumnsتنكتب مرة وتتكرر كل Refresh
DATEVALUETable.TransformColumnTypes مع "en-GB"en-GB تقول له اليوم قبل الشهر

ليش كل هذا بدل ما تنسخين وتلصقين؟ لأن النسخ يصير كل يوم ويغلط مرة بالأسبوع. هنا الغلط يصير مرة وحدة وقت الإعداد، وبعدين Refresh.

الخطوة 5

الداشبورد اليومي: بطاقة بطاقة

صفحة "Daily meeting" في اللوحة الموحدة اتغيرت: حماية أول شي. هذا شكلها الجديد، وتحته تفصيل كل عنصر.

خلفية صفحة الاجتماع اليومي

الصف الأول: ست بطاقات

#البطاقةالرقم الكبير (المقياس)السطر الصغيرليش هنا
1HEMAYA assigned to Mechanical أحمرH Assigned Mech: عدد الملاحظات اللي Owner dept = MechanicalH Sub assigned: Open X · overdue Yهذا شغل القسم المعلق. أحمر لأنه يحتاج فعل
2HEMAYA raised by Mechanical أخضرH Raised Mech: عدد الملاحظات اللي Raised dept = MechanicalH Sub raised: This month N · count onlyمشاركة الفريق في السلامة. عدد فقط مثل ما طلبتي
3Production yesterdayD Actual yesterday: مجموع Actual MT ليوم قبل تاريخ الاجتماعالهدف والنسبةالرقم اللي يسأل عنه المدير أول
4Downtime yesterday, hD Downtime yesterdayيفسر رقم الإنتاج
5Concerns openD Concerns openكم فات موعدهالمتابعات
6Condition alertsD CM openكم بمستوى Dangerمراقبة الحالة

المقاييس الجديدة بالكامل (في جدول _Measures، مجلد 01 HEMAYA)

H Assigned Mech         = CALCULATE ( COUNTROWS ( HEMAYA_Log ), HEMAYA_Log[Owner dept] = "Mechanical" ) + 0
H Assigned Mech open    = CALCULATE ( COUNTROWS ( HEMAYA_Log ), HEMAYA_Log[Owner dept] = "Mechanical", HEMAYA_Log[Status] <> "Closed" ) + 0
H Assigned Mech overdue = CALCULATE ( COUNTROWS ( HEMAYA_Log ), HEMAYA_Log[Owner dept] = "Mechanical", HEMAYA_Log[Overdue] = 1 ) + 0
H Raised Mech           = CALCULATE ( COUNTROWS ( HEMAYA_Log ), HEMAYA_Log[Raised dept] = "Mechanical" ) + 0
H Raised Mech month     =
VAR ref = CALCULATE ( MAX ( HEMAYA_Log[Reported] ), ALL ( HEMAYA_Log ) )
RETURN CALCULATE ( COUNTROWS ( HEMAYA_Log ), HEMAYA_Log[Raised dept] = "Mechanical",
                   HEMAYA_Log[Reported] >= DATE ( YEAR ( ref ), MONTH ( ref ), 1 ) ) + 0
H Sub assigned = "Open " & FORMAT ( [H Assigned Mech open], "#,0" ) & "   ·   overdue " & FORMAT ( [H Assigned Mech overdue], "#,0" )
H Sub raised   = "This month " & FORMAT ( [H Raised Mech month], "#,0" ) & "   ·   count only"
  • + 0 في الآخر: عشان تطلع 0 بدل فراغ لما ما فيه شي.
  • Overdue: عمود محسوب في Power Query: مو مقفلة وتاريخ الهدف فات.
  • "هذا الشهر" يُحسب من آخر تاريخ رصد في البيانات، مو من تاريخ اليوم، عشان الأرقام ما تصير أصفار لو البيانات متأخرة يومين.

الصف الثاني: الجدول والرسم

العنصرالنوعالحقولالفلترالترتيبالموقع والمقاس
HEMAYA assigned to Mechanical, still openTableLocation · Type · What happened · Corrective action (يظهر باسم "How to close it") · Owner · Status pill · AgeOwner dept = Mechanical و IsClosed = 0Days open تنازلي (الأقدم فوق)108, 240 · 746 × 190
Reports raised per employeeClustered barالمحور: Raised by · القيمة: H Total (يظهر باسم Reports)Raised dept = Mechanicalبالعدد تنازلي896, 240 · 352 × 190

ليش المفتوحة بس في الجدول؟ لأن الاجتماع الصباحي يبغى "وش باقي علينا"، والمقفلة موجودة في صفحة HEMAYA الكاملة. وليش الأقدم فوق؟ لأن الأقدم هو الأخطر، وشارة Age تلونه برتقالي بعد 30 يوم وأحمر بعد 60.

الصف الثالث

العنصرالنوعالحقولالفلترالموقع والمقاس
Production against targetLine & clustered columnالمحور: Meeting date · الأعمدة: D Prod trend actual · الخط: D Prod trend target108, 504 · 352 × 188
Today's planTableActivities: Area · Activity · Work order · Crew · StatusWhen = Today502, 504 · 352 × 188
Concerns and follow-upsTableConcerns: Area · Concern · Owner · DueStatus ≠ Closed896, 504 · 352 × 188

أرقام تتحققين منها بعد Refresh (البيانات التجريبية)

البطاقةالمفروضكيف طلعت
HEMAYA assigned to Mechanical100Owner في: Area engineer 24 + Foreman A 24 + Foreman B 20 + Foreman C 18 + Mechanical supervisor 14
HEMAYA raised by Mechanical96Raised by في: Foreman C 24 + Area engineer 20 + Foreman A 19 + Rawabi 18 + Foreman B 15
الرسم: أعلى موظفForeman C = 24ترتيب تنازلي

لو طلع عندك 0 في البطاقتين: يا الاستعلام HEMAYA_People ما انقرأ، يا الأسماء في People مو مطابقة للأسماء في السجل.

لو بتبنينها بنفسك في Power BI (بدون الملف الجاهز)

  1. Power Query: أضيفي الاستعلام HEMAYA_People، وفي استعلام HEMAYA_Log أضيفي Merge مرتين (Owner ثم Raised by) وExpand عمود Department، وسمّيهم Owner dept و Raised dept، وبدّلي null بـ Other.
  2. المقاييس السبعة فوق في جدول _Measures.
  3. الصف الأول: 6 بطاقات Card بالترتيب في الجدول، الرقم DIN 22، والسطر الصغير Segoe UI 7.5 رمادي.
  4. الجدول: Filters on this visual ← Owner dept is Mechanical، وIsClosed is 0. Sort ← Days open ← Descending.
  5. الرسم: Clustered bar، Raised by على المحور، H Total في القيم، فلتر Raised dept = Mechanical، Data labels on، لون ذهبي.

التفاصيل الكاملة لكل الصفحات (المواقع بالبكسل والكود) في دليل بناء Maintenance Hub.

انتبهي

الفخاخ

الفخوش يصيرالحل
اسم بمسافة زايدة أو حرف كبير مختلفPower Query ما يطابقه، والقسم يطلع OtherTable.TransformColumns مع Text.Trim، أو صححي الاسم في People
نفس الملاحظة في الملفينتنعد مرتينبعد Combine أضيفي Table.Distinct(All, {"ID"})
ID فاضي في ملف المقاولالصف ينحذف في NoBlankاصنعي ID: "CON-" & Date.ToText([Reported],"yyyyMMdd") & "-" & Text.From([Index])
تاريخ يوم/شهر يتفسر شهر/يوم10/09 يصير 9 أكتوبر"en-GB" في TransformColumnTypes
حالة مكتوبة "closed" أو "CLOSED"ما تنحسب مقفلةText.Proper على عمود Status

آخر تحديث 14 سبتمبر 2026. القالب: 05_Daily_Meeting\3_Output\HEMAYA_Merge_Template.xlsx