稲枝の押入れ

いなえが適当なことを書いては、しまっておく場所

Excelでセル内の文字列を取得しようとすると途中で途切れる

くっそくだらないが引っかかったのでメモ

タイトルの通り、C#Microsoft.Office.Interop.Excelを使ってセルの内容を取得していたら、一定の長さ以上の文字列について取り出しに失敗しているのに気づいた。

簡単なサンプルコードは以下。

とりあえず、1行目,1列目にaと10000文字入力したエクセルファイル、test.xlsxを用意してあるという前提だ。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CS_Test
{
    class Program
    {

        /// <summary>
        /// ガベージコレクションを実行
        /// </summary>
        static void ExecGC()
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
        }

        /// <summary>
        /// COMオブジェクトの解放
        /// </summary>
        /// <param name="obj">開放したいCOMオブジェクト</param>
        static void ReleaseCOMObject(object obj)
        {
            // EXCELのCOMオブジェクトを開放する
            if (obj != null)
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
                obj = null;
            }
        }

        /// <summary>
        /// エクセルアプリケーションの解放
        /// </summary>
        /// <param name="app">excelアプリケーション</param>
        static void ReleaseExcel(Microsoft.Office.Interop.Excel.Application app)
        {
            // EXCELのCOMオブジェクトを開放する
            if (app != null)
            {
                app.Quit();
                System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
                app = null;
            }
        }

        /// <summary>
        /// エントリポイント
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            Microsoft.Office.Interop.Excel.Application excel = null;
            Microsoft.Office.Interop.Excel.Workbooks books = null;
            Microsoft.Office.Interop.Excel.Workbook book = null;
            Microsoft.Office.Interop.Excel.Sheets sheets = null;
            Microsoft.Office.Interop.Excel.Worksheet sheet = null;
            try
            {
                excel = new Microsoft.Office.Interop.Excel.Application();
                books = excel.Workbooks;
                book = books.Open(System.IO.Path.GetFullPath("test.xlsx"));
                sheets = book.Worksheets;
                sheet = sheets[1];

                //1行目、1列目を取得
                string cell1 = (sheet.Cells[1, 1]).Text;
                System.Console.WriteLine($".Textで抜き出したテキストのサイズ {cell1.Length}");
                string cell2 = (sheet.Cells[1, 1]).Value;
                System.Console.WriteLine($".Valueで抜き出したテキストのサイズ {cell2.Length}");

                System.Console.ReadKey();
            }
            finally
            {
                ReleaseCOMObject(sheet);
                ReleaseCOMObject(sheets);
                ReleaseCOMObject(book);
                ReleaseCOMObject(books);
                //一旦解放
                ExecGC();
                // EXCELのCOMオブジェクトを開放する
                ReleaseExcel(excel);
                //再度解放
                ExecGC();
            }
        }
    }
}

実行結果

.Textで抜き出したテキストのサイズ 8221
.Valueで抜き出したテキストのサイズ 10000

というわけで、 .Textで取り出すと8221文字以上は取り出せない

如何にもな名前だが、長い文字列を取り出したくても.Textを使ってはならない。.Valueを使おう。

ValueとTextの違いについてはExcelでセルの値を扱う(Value、Value2、Text、Formulaの違いのメモ)などをみるといい。

因みにMS公式のRange.Textに関するドキュメントにはこんなことどこにも書いていない。やりますねえ。

勿論僕はデータ作成者ではなく、Excelを処理したいと言われたらただ処理をするプログラムを書くだけだ。書くだけなのだが、そもそもとしていいたい。
1つのセルにこんなに大量の文字列を入れるのはやめましょう。