Domanda

Usiamo un foglio di Excel che contiene una logica di business (e così è spesso a cura di non-IT). Codice Alcuni C ++ è generato in VBA dallo stesso foglio - sciocco, lo so. Ho intenzione di scrivere una serie di test di unità contro questo foglio di lavoro, garantendo formato rigorosa per il bene di tutti. Per esempio, le cose dovrebbero essere in ordine alfabetico. Non ho fatto questo tipo di lavoro prima; non sono nemmeno sicuro che libreria da utilizzare. Per ottenere i miei piedi bagnati, mi piacerebbe trovare tutte le cellule che hanno carattere diverso da "automatica del colore, lo stile semplice, Arial, dimensione 10" - per esempio rosso o in grassetto o in taglia 11, o di carattere Comic Sans. Poi voglio verificare se queste cellule sono cellule "non-header". Le cellule "header" sono quelli che fanno parte di noti intervalli denominati. Per esempio, se tale cellula fa parte di una gamma "XYZheaders", dal nome, allora è ok. Se no, allora desidero segnalare le coordinate di una cella (idealmente come qualcosa di leggibile come "D25" per ogni cellula che ha un problema, così come indicare se il problema è con il colore, il tipo di carattere, lo stile, o la dimensione .

EDIT: Ho appena messo taglia su questa domanda perché sto cercando un campione completo C #. Si prega di fare domande se si pensa che la mia domanda è ambigua.

È stato utile?

Soluzione

Ecco la mia soluzione. Ho provato con alcuni file Excel 2007 (.xlsx). Il programma può essere costruito utilizzando VS 2010 (target .NET 4) con i seguenti quattro riferimenti: Microsoft.CSharp, Microsoft.Office.Interop.Excel, Sistema e System.Core.

Utilizzando .NET 4 rende un po 'più facile lavorare con Excel.

In ogni caso ecco il codice:

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));
        }
    }
}

Il programma assume il nome di un file di Excel come primo argomento. Questo file viene aperto e ogni cella è testato contro diversi di font-criteri. Le cellule con "non-default-font" è testato contro il chiamato a distanza, e quelli che cadono al di fuori di questi intervalli sono uscita alla console.

Come al solito un po 'di ErrorHandling dovrebbe essere aggiunto al programma -. Ma spero che questo dovrebbe iniziare

Altri suggerimenti

Questo dovrebbe fare il trucco, godere. Tenete a mente che mettere in nuovi nomi di intervallo non si innescherà un Recalc di una cella che contiene questa funzione (in modo da colpire F9 dopo la creazione di nomi di intervallo).

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top