كيفية اختبار ما إذا كانت أي خلية غير رئيس في ملف Excel جريئًا أو مائلًا

StackOverflow https://stackoverflow.com/questions/3188303

سؤال

نستخدم ورقة Excel التي تحتوي على بعض منطق الأعمال (وبالتالي يتم تحريرها غالبًا من قبل غير IT). يتم إنشاء بعض كود C ++ في VBA من نفس الورقة - سخيفة ، وأنا أعلم. أخطط لكتابة مجموعة من اختبارات الوحدة مقابل ورقة العمل هذه ، مما يضمن تنسيقًا صارمًا لصالح الجميع. على سبيل المثال ، يجب فرز الأشياء أبجديًا. لم أفعل هذا النوع من العمل من قبل ؛ لست متأكدا حتى المكتبة التي يجب استخدامها. للحصول على قدمي رطبة ، أود أن أجد جميع الخلايا التي لها خط غير "اللون التلقائي ، النمط العادي ، العالي ، الحجم 10" - على سبيل المثال الأحمر أو الجريء أو الحجم 11 ، أو Comicsans الخط. ثم أريد التحقق مما إذا كانت هذه الخلايا هي خلايا "غير رأس". خلايا "الرأس" هي تلك التي تشكل جزءًا من النطاقات المعروفة. على سبيل المثال ، إذا كانت هذه الخلية تنتمي إلى نطاق اسم "Xyzheaders" ، فلا بأس بذلك. إذا لم يكن الأمر كذلك ، فإنني أرغب في الإبلاغ عن إحداثيات الخلية (من الناحية المثالية كشيء قابل للقراءة للإنسان مثل "D25" لكل خلية لديها مشكلة ، وكذلك الإشارة إلى ما إذا كانت المشكلة مع اللون أو نوع الخط أو الأسلوب أو الحجم .

تعديل: أنا فقط وضعت Bounty على هذا السؤال لأنني أبحث عن عينة C# كاملة. الرجاء طرح الأسئلة إذا كنت تعتقد أن سؤالي غامض.

هل كانت مفيدة؟

المحلول

هذا هو الحل. لقد اختبرته مع بعض ملفات Excel 2007 (.xlsx). يمكن بناء البرنامج باستخدام VS 2010 (الاستهداف .NET 4) مع المراجع الأربعة التالية: Microsoft.csharp ، Microsoft.office.interop.excel ، System و System.Core.

استخدام .NET 4 يجعل من الأسهل بعض الشيء العمل مع Excel.

على أي حال ، إليك الرمز:

using System;
using System.Collections.Generic;
using System.Linq;
using Excel = Microsoft.Office.Interop.Excel;

namespace ExcelTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Excel.Application excelapplication = null;
            Excel.Workbook workbook = null;

            try
            {
                excelapplication = new Excel.Application();
                workbook = excelapplication.Workbooks.Open(args[0]);
                var errors = new Dictionary<string, List<string>>();
                foreach (Excel.Worksheet sheet in workbook.Sheets)
                {
                    int rowCount = sheet.UsedRange.Cells.Rows.Count;
                    int colCount = sheet.UsedRange.Cells.Columns.Count;
                    var usedCells = sheet.UsedRange.Cells;

                    for (int i = 1; i <= rowCount; i++)
                    {
                        for (int j = 1; j <= colCount; j++)
                        {
                            Excel.Range range = usedCells[i, j];
                            List<string> cellErrors;
                            if (HasNonDefaultFont(range, out cellErrors))
                            {
                                if (!IsHeaderCell(workbook, range))
                                {
                                    string cellDisplayTitle = String.Format("{0}!{1}", sheet.Name, range.Address);
                                    errors[cellDisplayTitle] = cellErrors;
                                }
                            }
                        }
                    }
                }
                ReportErrors(errors);
            }
            finally
            {
                if (workbook != null)
                    workbook.Close();
                if (excelapplication != null)
                    excelapplication.Quit();
            }
        }

        static bool HasNonDefaultFont(Excel.Range range, out List<string> differences)
        {
            differences = new List<string>();

            if (range.Font.Color != 0.0)
                differences.Add("Has font-color");

            if (range.Font.Bold)
                differences.Add("Is bold");

            if (range.Font.Italic)
                differences.Add("Is italic");

            if (range.Font.Underline != (int)Microsoft.Office.Interop.Excel.XlUnderlineStyle.xlUnderlineStyleNone)
                differences.Add("Is underline");

            if (range.Font.Strikethrough)
                differences.Add("Is strikethrough");

            if (range.Font.Name != "Arial")
                differences.Add(String.Format("Font is {0}", range.Font.Name));

            if (range.Font.Size != 10)
                differences.Add(String.Format("Font size is {0}", range.Font.Size));

            return differences.Count != 0;
        }

        static bool IsHeaderCell(Excel.Workbook workbook, Excel.Range range)
        {
            // Look through workbook names:
            foreach (Excel.Name namedRange in workbook.Names)
            {
                if (range.Parent == namedRange.RefersToRange.Parent && range.Application.Intersect(range, namedRange.RefersToRange) != null)
                    return true;
            }

            // Look through worksheet-names.
            foreach (Excel.Name namedRange in range.Worksheet.Names)
            {
                if (range.Parent == namedRange.RefersToRange.Parent && range.Worksheet.Application.Intersect(range, namedRange.RefersToRange) != null)
                    return true;
            }
            return false;
        }

        static void ReportErrors(Dictionary<string, List<string>> errors)
        {
            if (errors.Count > 0)
            {
                Console.WriteLine("Found the following errors:");
                Console.WriteLine("---------------------------------");
                Console.WriteLine("{0,-15} | Error", "Cell");
                Console.WriteLine("---------------------------------");
            }

            foreach (KeyValuePair<string, List<string>> kv in errors)
                Console.WriteLine("{0,-15} | {1}", kv.Key, kv.Value.Aggregate((e, s) => e + ", " + s));
        }
    }
}

يفترض البرنامج اسم ملف excel كحجة الأولى. يتم فتح هذا الملف ويتم اختبار كل خلية ضد معايير الخطوط المختلفة. يتم اختبار الخلايا التي تحتوي على "غير مرفقة" مقابل المسمى ، وتكون تلك التي تقع خارج هذه النطاقات ناتج إلى وحدة التحكم.

كالعادة يجب إضافة بعض الأخطاء إلى البرنامج - ولكن نأمل أن يبدأ هذا.

نصائح أخرى

هذا يجب أن يفعل الخدعة ، استمتع. ضع في اعتبارك أن وضع أسماء نطاقات جديدة لن يؤدي إلى إعادة حساب خلية تحتوي على هذه الوظيفة (لذلك ضرب F9 بعد إنشاء أسماء النطاق).

Option Explicit

Public Function IsDataCellBoldOrItalic() As Boolean
    Dim rngName As Name
    Dim intersectRange As Name

    For Each rngName In ActiveWorkbook.Names
        If Not Intersect(rngName.RefersToRange, Application.ThisCell) Is Nothing Then
            IsDataCellBoldOrItalic = False
            Exit Function
        End If
    Next

    ''# Now we know we are not in a "header" cell
    IsDataCellBoldOrItalic = Application.ThisCell.Font.Bold Or Application.ThisCell.Font.Italic

End Function
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top