7

重複の可能性:
Excelシートで占有セルの範囲を取得する方法

Excel ワークシートで最後に使用された行を見つけようとしています。これを行うために、私はこのコードを使用しています:

int lastUsedRow = currentWS.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell,Type.Missing).Row;

ほとんどの場合、問題なく動作しますが、Excel は、シートに想定よりも多くの行があると判断することがあります。

Fx: 12 行を含むシート 1 から空のシート 2 にデータをコピーし、右クリックして [削除...] を押してシート 2 のすべてのデータを削除し、5 行を含むシート 3 からシート 2 にデータをコピーすると、 lastUsedRow は、5 である必要がある 12 の値を与えてくれます。

ここに画像の説明を入力 上の画像の例では、行数として 22 の値を与えると想定していますが、代わりに 634 を取得します。右側のスクロール バーに注目してください。

Excel は、すべてのセルを削除したにもかかわらず、新しいデータをより少ない行でシートにコピーする前に、一部のセルが塗りつぶされていると考えているようです。

シート内のデータのビューを「サイズ変更」して、使用されたセルの正しい数を取得する方法、または最後に使用された行の数を見つける別の方法はありますか?

ありがとう。

4

3 に答える 3

12

編集:新しいソリューション

ジョーが最後に使用された行を取得するための正しいコードを提供したためです。

Worksheet.UsedRange.Row + Worksheet.UsedRange.Rows.Count - 1 

次のコマンドを使用して、コンテンツとフォーマットをクリアします

Selection.Delete
Selection.ClearFormats

これはうまくいくはずです;)

于 2012-09-05T08:36:24.770 に答える
5

ワークシートで最後に使用された行を取得するには、次を使用できます。

Worksheet.UsedRange.Row + Worksheet.UsedRange.Rows.Count - 1

ご了承ください:

  • UsedRange は必ずしも最初の行から始まるとは限りません。最初の行は空である可能性があります。

  • UsedRange には、コンテンツが空の場合でも書式設定を含むセルが含まれます。これが、予想よりも大きな値が表示されている理由だと思います。空のセルから書式設定とデータを削除する必要があります。

プログラムでセルの書式設定を削除する方法がわかりません

を使用Range.ClearFormatsして、書式設定をクリアしたりRange.Clear、すべてをクリアしたりできます。一般に、Excel でプログラムを使用して何かを実行する方法がわからない場合は、マクロを記録して手動で実行し、生成されたマクロを調べてみてください。

于 2012-09-05T09:09:07.533 に答える
4

私が使用するコードは次のとおりです。

public static string GetMinimalUsedRangeAddress(Excel.Worksheet sheet)
{
    string address = String.Empty;
    try
    {
        int rowMax = 0;
        int colMax = 0;

        Excel.Range usedRange = sheet.UsedRange;
        Excel.Range lastCell = usedRange.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing);
        int lastRow = lastCell.Row;
        int lastCol = lastCell.Column;
        int rowMin = lastRow + 1;
        int colMin = lastCol + 1;

        int rr = usedRange.Rows.Count;
        int cc = usedRange.Columns.Count;
        for (int r = 1; r <= rr; r++)
        {
            for (int c = 1; c <= cc; c++)
            {
                Excel.Range cell = usedRange.Cells[r, c] as Excel.Range;
                if (cell != null && cell.Value != null && !String.IsNullOrEmpty(cell.Value.ToString()))
                {
                    if (cell.Row > rowMax)
                        rowMax = cell.Row;
                    if (cell.Column > colMax)
                        colMax = cell.Column;
                    if (cell.Row < rowMin)
                        rowMin = cell.Row;
                    if (cell.Column < colMin)
                        colMin = cell.Column;
                }
                MRCO(cell);
            }
        }

        if (!(rowMax == 0 || colMax == 0 || rowMin == lastRow + 1 || colMin == lastCol + 1))
            address = Cells2Address(rowMin, colMin, rowMax, colMax);

        MRCO(lastCell);
        MRCO(usedRange);
    }
    catch (Exception ex)
    {
        // log as needed
    }
    return address; // caller should test return for String.Empty
}


public static string Cells2Address(int row1, int col1, int row2, int col2)
{
    return ColNum2Letter(col1) + row1.ToString() + ":" + ColNum2Letter(col2) + row2.ToString();
}


public static string ColNum2Letter(int colNum)
{
    if (colNum <= 26) 
        return ((char)(colNum + 64)).ToString();

    colNum--; //decrement to put value on zero based index
    return ColNum2Letter(colNum / 26) + ColNum2Letter((colNum % 26) + 1);
}


public static void MRCO(object obj)
{
    if (obj == null) { return; }
    try
    {
        System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
    }
    catch
    {
        // ignore, cf: http://support.microsoft.com/default.aspx/kb/317109
    }
    finally
    {
        obj = null;
    }
}

注: 個々のセル値チェックをすべて に置き換えたくなるかもしれませんがCountA、場合によっては失敗します。たとえば、セルに式 が含まれている場合=IF(A1=55,"Y","")、結果の空の文字列は、 を使用して空白以外のセルとしてカウントされますCountA

于 2012-09-05T10:41:53.587 に答える