Как проверить, является ли любая ячейка без заголовка в файле Excel жирным шрифтом или курсивом? - PullRequest
3 голосов
/ 06 июля 2010

Мы используем лист Excel, который содержит некоторую бизнес-логику (и поэтому он часто редактируется не-IT).Некоторый код C ++ генерируется в VBA из того же листа - глупо, я знаю.Я планирую написать несколько модульных тестов на этом листе, обеспечивая строгий формат для всех.Например, вещи должны быть отсортированы в алфавитном порядке.Я не делал такую ​​работу раньше;даже не уверен, какую библиотеку использовать.Чтобы намочить ноги, я хотел бы найти все ячейки, в которых есть шрифт, отличный от «автоматический цвет, обычный стиль, Arial, размер 10», например красный или жирный или размер 11 или шрифт ComicSans.Затем я хочу проверить, являются ли эти ячейки ячейками без заголовка.Ячейки "заголовка" - это ячейки, которые являются частью известных именованных диапазонов.Например, если такая ячейка относится к именованному диапазону «XYZheaders», то это нормально.Если нет, то я хочу сообщить координаты ячейки (в идеале, как что-то удобочитаемое для человека, например «D25») для каждой ячейки, в которой есть проблема, а также указать, связана ли проблема с цветом, типом шрифта, стилем или размером..

РЕДАКТИРОВАТЬ: Я просто положил награду за этот вопрос, потому что я ищу полный образец C #. Пожалуйста, задавайте вопросы, если вы считаете, что мой вопрос неоднозначный.

Ответы [ 2 ]

3 голосов
/ 24 июля 2010

Вот мое решение.Я проверил это с некоторыми файлами 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в качестве первого аргумента.Этот файл открывается, и каждая ячейка проверяется на соответствие различным критериям шрифта.Ячейки с «non-default-font» проверяются на соответствие именованному диапазону, а те, которые выходят за пределы этих диапазонов, выводятся на консоль.

Как обычно, в программу следует добавить некоторую обработку ошибок - но, надеюсьэто должно начать вас.

3 голосов
/ 07 июля 2010

Это должно сработать, наслаждайтесь. Имейте в виду, что добавление новых имен диапазонов не вызовет пересчет ячейки, содержащей эту функцию (поэтому после создания имен диапазонов нажмите 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
...