2

特定の値について一連の 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ステートメントの 1 つだけが真であることはわかっています。

s の長いシーケンス以外に、この関数をより簡潔に記述する方法はありifますか?

4

6 に答える 6

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;
            }
        } 
    }
于 2012-11-20T00:00:22.313 に答える
1

セルの値が一貫していないように見えるため、すべてのパラメーターをカスタム オブジェクトのリストに入れることができます。

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

List<Version>次に、さまざまなバージョンをロードします。その後、リストでループを使用してforeach、そのうちの 1 つにヒットしたときに反応することができます。

于 2012-11-20T00:01:03.077 に答える
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 
    }
于 2012-11-20T00:21:35.747 に答える
0

残りの if ブロックが投稿されたサンプルと同じ構造である場合、ここに明確なパターンがあります。文字列「Changes for Version」の存在をより大きな範囲 (例: 「a1:a4」) で確認し、その文字列を返し、返したい整数を解析できませんでしたか。少し考えを改めれば、2~3LOCまで倒せるはず?

説明するコード。

    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;
    }
于 2012-11-20T00:05:41.650 に答える
0

.Net 4.0 Excel Interop では、アンダースコア _Types を使用する必要はなく、角かっこを使用します。

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;
            }
        }
    }
}
于 2012-11-19T23:57:13.763 に答える
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

于 2012-11-20T00:13:11.913 に答える