Как проверить, выделена ли какая-либо ячейка, не относящаяся к заголовку, в файле Excel жирным шрифтом или курсивом

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

Вопрос

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

Редактировать: Я просто ответил на этот вопрос, потому что я ищу полный образец C #.Пожалуйста, задавайте вопросы, если вам кажется, что мой вопрос неоднозначен.

Это было полезно?

Решение

Вот мое решение.Я протестировал это с некоторыми файлами Excel 2007 (.xlsx).Программа может быть собрана с использованием VS 2010 (ориентирована на .NET 4) со следующими четырьмя ссылками:Майкрософт.CSharp, Microsoft.Офис.Взаимодействие.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