如何重构一系列if-then语句?

时间:2012-11-19 23:48:28

标签: c# excel

我正在编写一个脚本来检查一堆Excel电子表格中的某些值,我已经找到了这样的代码:

    public bool checkContents(Excel._Worksheet sht, string address, string cellValue)
    {
        Excel.Range tempRange = sht.get_Range(address);
        return Convert.ToString(tempRange.Value) == cellValue;
    }

    public string getVersion(Excel._Worksheet sht)
    {
        if (checkContents(sht,"a4","Changes for Version 24"))
        {
            return "24";
        }
        else if (checkContents(sht,"a1","Changes for Version 23 (Official)"))
        {
            return "23";
        }
        else if (checkContents(sht,"a2","Changes for Version 22"))
        {
            return "22";
        }


       //and so on for another 10 if-else blocks 
    }

我知道对于给定的工作表,只有if个语句中的一个是真的。

除了if s的长序列之外,是否有更简洁的方法来编写此函数?

6 个答案:

答案 0 :(得分:4)

您可以尝试这样的事情(未经测试,因此可能会出现一些语法错误)

    private class VersionSpec
    {
        public string Address { get; private set; }
        public string CellValue { get; private set; }
        public string Version { get; private set; }

        public VersionSpec (string address, string cellValue, string version)
        {
            Address = address;
            CellValue = cellValue;
            Version = version;
        }
    }

    public string getVersion(Excel._Worksheet sht)
    {
        VersionSpec[] versionSpecs = new []
        {
            new VersionSpec("a4", "Changes for Version 24", "24"),
            new VersionSpec("a1", "Changes for Version 23 (Official)", "23"),
            new VersionSpec("a2", "Changes for Version 22", "22"),
            // other versions...
        }

        foreach(VersionSpec versionSpec in versionSpecs)
        {
            if(checkContents(sht, versionSpec.Address, versionSpec.CellValue))
            {
                return versionSpec.Version;
            }
        } 
    }

答案 1 :(得分:1)

由于您的单元格值看起来不一致,您可以将所有参数放入自定义对象列表中,这类似于。

public class Version
{
    public string CellAddress { get; set; }
    public string CellValue { get; set; }
    public string ReturnValue { get; set; }
}

然后使用各种版本加载List<Version>。之后,您可以在列表中使用foreach循环,并在获得其中一个循环时做出反应。

答案 2 :(得分:0)

使用.Net 4.0 Excel Interop,您不需要使用下划线类型,而使用方括号。

public bool checkContentsStartsWith(Worksheet sht, string address, string cellValue)
{
   Range tempRange = sht.Range[address];
  return cellValue.StartsWith(tempRange.Value2);
}

public string getVersion(Worksheet sht)
{
    for (int j = 1; j < 4;j++)
    {
        for (int i = 24; i > 0; i--)
        {
            if (checkContentsStartsWith(sht, "A" + j.ToString(), "Changes for Version " + i))
            {
                return i;
            }
        }
    }
}

答案 3 :(得分:0)

如果剩下的if-blocks与发布的样本结构相同,那么这里有一个清晰的模式;你不能检查更大的范围(例如“a1:a4”)是否存在字符串“Changes for Version”,返回该字符串,并解析出你想要返回的整数。如果你稍微调整一下你的想法,你应该能够将其降低到2-3 LOC吗?

要阐明的一些代码;

    public static string getVersion(Worksheet sht)
    {
        Range range = sht.Range["A1:A10"];
        foreach (Range c in range.Cells)
        {
            if (null == c.Value2) continue;
            string val = c.Value.ToString();
            if (val.Contains("Changes for Version "))
            {
                int startIndex = ("Changes for Version ").Length;
                return val.Substring(startIndex, 2).Trim(); 
            }
        }

        return null;
    }

答案 4 :(得分:0)

我有另一个答案:

using (var usedRange = sheet.UsedRange.WithComCleanup())
{
    string firstAddress = string.Empty;
    string nextAddress = string.Empty;
    using (var firstCell = usedRange.Resource.Find("Changes for Version", LookIn: XlFindLookIn.xlValues).WithComCleanup())
    {    
        if (firstCell.Resource != null)
        {
            firstAddress = firstCell.Resource.Address;
            AppendListOfVersion(sheet.Name, firstCell.Resource);
            nextAddress = firstAddress;
        }
    }
}
if (firstAddress != "") // the first Find attempt was successful, so keep looking (FindNext)
{
    var keepLooking = true;
    while (keepLooking)
    {
        using (var prevCellToFindNextFrom = sheet.Range[nextAddress].WithComCleanup())
        using (var nextCell = usedRange.Resource.FindNext(prevCellToFindNextFrom.Resource).WithComCleanup())
        {
            if (nextCell.Resource == null)
                keepLooking = false;
            else
            {
                nextAddress = nextCell.Resource.Address;
                if (nextAddress == firstAddress)
                    keepLooking = false;
                else
                    AppendListOfVersion(sheet.Name, nextCell.Resource);
            }
        }
    }
}

您可以在此处了解WithComCleanUp():http://jake.ginnivan.net/vsto-com-interop

答案 5 :(得分:0)

以下是几个选项:

    public string getVersion(Excel._Worksheet sht)
    {
        if (checkContents(sht, "a4", "Changes for Version 24"))
            return "24";
        if (checkContents(sht, "a1", "Changes for Version 23 (Official)"))
            return "23";
        if (checkContents(sht, "a2", "Changes for Version 22"))
            return "22";
        //and so on for another 10 if-else blocks 
    }


    public string getVersion(Excel._Worksheet sht)
    {
        string[][] values = new string[3][]{
                            new string[3]{"a4","Changes for Version 24","24"}
                            ,new string[3]{"a1", "Changes for Version 23 (Official)","23"}
                            ,new string[3]{"a2", "Changes for Version 22","22"}
                          };
        foreach (string[] strings in values)
        {
            if (checkContents(sht, strings[0], strings[1])) return strings[2];
        }
        return null; //or throw not found error 
    }