9

OLEDB を使用して Excel スプレッドシートからワークシート名を取得する際に問題があります。問題は、GetOleDbSchemaTable を使用すると、結果の DataTable に実際のワークシート名以上のものがあることです。Excelによって内部的に使用されていると想定できる「テーブル」の余分な行があります。

たとえば、myWorksheet という名前のワークシートがある場合、以下のコードは、myWorksheet$、myWorksheet$PrintTable、および myWorksheet$_ を含むリストになる可能性があります。最初の myWorksheet$ レコードのみが実際のワークシート用です。他は要らないゴミです。それらをメタデータで見ると、TABLE 型であっても通常のテーブルのように見えます。

今のところ、名前に「$_」または「$Print」が含まれているものを手動で除外しましたが、他の Excel 機能によってこれらの余分なレコードが別の形式で表示される可能性があることは誰にもわかりません。

ワークシートではないこれらの内部テーブルではなく、実際のワークシート名のみを取得する最良の方法を知っている人はいますか? メタデータにそれらを区別するものはありますか?

 private ArrayList getXlsWorksheetNames(OleDb.OleDbConnection conn)
    {
        ArrayList wsList = new ArrayList();
        DataTable schemaTable;

        try
        {
            conn.Open();
            schemaTable = conn.GetOleDbSchemaTable(OleDb.OleDbSchemaGuid.Tables, null);

            foreach (DataRow row in schemaTable.Rows)
            {
                //form.appendToResultsTxt("Adding worksheet to list: " + Environment.NewLine +
                //    "Name = " + row.Field<string>("TABLE_NAME") + "," + Environment.NewLine +
                //    "Type = " + row.Field<string>("TABLE_TYPE") + "," + Environment.NewLine + Environment.NewLine);
                wsList.Add(row.Field<string>("TABLE_NAME"));
            }
            conn.Close();
        }
        catch (Exception ex)
        {
            if (this.mode == Cps2TxtUtilModes.GUI_MODE)
            {
                this.form.appendToResultsTxt(ex.ToString());
            }
            throw;
        }

        return wsList;
    }

このリンクの記事を読みましたが、彼らは私とは違うことをしているようには見えず、ワークシート以外の余分なテーブルをフィルタリングして除外しているようには見えないため、Microsoft は正しい答え。

http://support.microsoft.com/kb/318452

また、以下のリンクのスレッドのように、多くの StackOverflow も調べましたが、これは役に立ちましたが、この 1 つの問題は解決しません。

Excel OleDbを使用してシート名をシート順に取得する

誰かが尋ねる前に、私はスプレッドシートで使用されている機能を実際に制御できないことも言いたいと思います。表を印刷する」。

どんなアイデアでも大歓迎です。ありがとう!

4

4 に答える 4

2

経験上、名前がドル記号で終わる人ばかりのようです。データには存在しない追加のワークシートが表示されているように見えるクライアントからのシナリオに遭遇しました-これらは後で Excel の非表示のワークシートであることが判明しました!

于 2012-05-18T15:34:21.450 に答える
0

私の頭に浮かぶ最初の方法は、ExcelOleDbを 使用してシート名をシートオーダーで取得するリンクにリストされているakash88と同じ方法です。

akash88のアプローチを採用し、コードを読みやすくするために少しクリーンアップすることができます。

        var wsList = from s in schemaTable
                     where s.Field<string>("TABLE_NAME").Contains("$")
                     select s.Field<string>("TABLE_NAME");
于 2012-10-05T18:56:48.097 に答える
0

以下EndsWith("$")のように代わりにテストできます。Contains("$")

List<String> lstsheetNames = new List<String>();
String sheetName;
foreach (DataRow row in schemaTable.Rows)
{
    sheetName = row.Field<string>("TABLE_NAME");
    String strTemp = sheetName.Split(' ');

    if(strTemp.Length == 1 && sheetName.EndsWith("$"))
       lstsheetNames.Add(sheetName.Substring(0, sheetName.Length - 1));

    else if(strTemp.Length > 1 && strTemp.GetValue(strTemp.Length - 1).ToString().EndsWith("$'"))
       lstsheetNames.Add(sheetName.Substring(1, sheetName.Length - 3));
}

このコードを同じ問題で使用しましたが、正常に動作します。

編集:申し訳ありませんが、私はこれに注意を払いませんでした.私は今コードを変更しました.それは最善または最短の方法ではないかもしれませんが、動作します.

于 2013-01-28T09:58:56.450 に答える