ReoGrid
遅延ロードによる大規模データの読み込みの高速化

このドキュメントでは、ReoGridで遅延ロードを使用して大規模データの読み込みを効率化する方法について説明します。具体的なコード例を通じて、遅延ロードの実装方法を紹介します。

ステップ1: ワークシートの初期化

まず、ワークシートを初期化し、ユーザーインターフェースコンポーネントを設定します。

public partial class LazyLoadPerformanceDemo : UserControl
{
    private Worksheet worksheet;

    public LazyLoadPerformanceDemo()
    {
        InitializeComponent();
    }

    public static int RECORD_COUNT = 1000000;
    public static int COLUMN_COUNT = 12;

    List<FlightLog> logs;

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        // データの生成
        logs = FlightLogGenerator.GenerateFlightLogs(RECORD_COUNT);
    }
}

ステップ2: データの生成

大規模なデータセットを生成するメソッドを作成します。この例では、フライトログデータを生成します。

public class FlightLogGenerator
{
    public static List<FlightLog> GenerateFlightLogs(int numRows = 10000)
    {
        Random rand = new Random();
        DateTime startTime = DateTime.Now;
        List<FlightLog> logs = new List<FlightLog>();

        string[] weatherOptions = { "晴れ", "曇り", "雨", "雪" };

        for (int i = 0; i < numRows; i++)
        {
            logs.Add(new FlightLog
            {
                Timestamp = startTime.AddMilliseconds(200 * i),
                Speed = Math.Round(rand.NextDouble() * 180, 2),
                Distance = Math.Round(rand.NextDouble() * 1000, 2),
                Throttle = rand.Next(0, 101),
                EngineBrake = rand.Next(0, 101),
                Fuel = Math.Round(rand.NextDouble() * 100, 2),
                DoorStatus = rand.Next(0, 2) == 1,
                GPSLatitude = Math.Round(35.0 + rand.NextDouble() * 10, 6),
                GPSLongitude = Math.Round(135.0 + rand.NextDouble() * 10, 6),
                Weather = weatherOptions[rand.Next(weatherOptions.Length)]
            });
        }

        return logs;
    }
}

ステップ3: データソースの作成

ワークシートにデータを提供するデータソースクラスを実装します。


// データソース
public class FlightLogDataSource : IDataSource<FlightlogDataRecord>
{
  public List<FlightLog> Logs { get; private set; }

  private FlightlogDataRecord[] initedRecords;

  public FlightLogDataSource(List<FlightLog> logs)
  {
    this.Worksheet = worksheet;
    this.Logs = logs;
    this.initedRecords = new FlightlogDataRecord[logs.Count];
  }

  public int RecordCount => Logs.Count;
  public int ColumnCount => LazyLoadPerformanceDemo.COLUMN_COUNT;

  public bool SuspendDataChangeEvent { get; set; }
  public event EventHandler<DataSourceChangedEventArgs> OnInputDataChanged;

  // 指定された行のデータを取得します
  public FlightlogDataRecord GetRecord(int row)
  {
    FlightlogDataRecord record = initedRecords[row];

    if (record == null)
    {
      record = new FlightlogDataRecord(this, row, Logs[row]);
    }

    // 行データを返却
    return record;
  }
}

// データレコード
public class FlightlogDataRecord : IDataRecord
{
    private FlightLogDataSource source;
    private int row;
    public FlightLog LogData { get; private set; }
    public FlightlogDataRecord(FlightLogDataSource source, int row, FlightLog logData)
    {
        this.source = source;
        this.row = row;
        this.LogData = logData;
    }

    public object GetData(int columnIndex) {
        switch (columnIndex)
        {
            case 0: return $"No. {row + 1}";
            case 1: return LogData.Timestamp;
            case 2: return LogData.Speed;
            case 3: return LogData.Distance;
            case 4: return LogData.Throttle;
            case 5: return LogData.EngineBrake;
            case 6: return LogData.Fuel;
            case 7: return LogData.DoorStatus;
            case 8: return LogData.GPSLatitude;
            case 9: return LogData.GPSLongitude;
            case 10: return LogData.Weather;
            case 11: return $"=ROUND({new CellPosition(row, 4).ToAbsoluteAddress()} / {new CellPosition(row, 5).ToAbsoluteAddress()}, 1)";
        }
        return null;
    }
}

ステップ4: 遅延読み込みでデータをロード

データソースを使用して、遅延読み込みモードでデータをワークシートにロードし、パフォーマンスを向上させます。

private void button1_Click(object sender, EventArgs e)
{
    // ワークシートの行数を変更
    worksheet.SetRows(logs.Count);

    // データソースを遅延読み込みモードで設定
    worksheet.AddDataSource(
        new RangePosition(0, 0, logs.Count, COLUMN_COUNT),
        new FlightLogDataSource(logs),
        // 遅延ロードを有効化
        DataSourceLoadMode.LazyLoading);
}

これらのステップに従うことで、データソースと遅延読み込みモードを使用して、ReoGridワークシートに大規模なデータセットを効率的にロードできます。

罫線およびセル書式の適用

GetRecordメソッドが呼び出される際に、罫線やセル書式の設定を行うことができます。

以下の例では、ワークシートインスタンスを使用して罫線などを設定します。


public class FlightLogDataSource : IDataSource<FlightlogDataRecord>
{
    public Worksheet Worksheet { get; private set; }
        
    private FlightlogDataRecord[] initedRecords;
    ...

    public FlightLogDataSource(Worksheet worksheet, List<FlightLog> logs)
    {
        this.Worksheet = worksheet;
        this.Logs = logs;
        this.initedRecords = new FlightlogDataRecord[logs.Count];
    }
    
    ...

    // GetRecord の部分を以下のように変更
    public FlightlogDataRecord GetRecord(int row)
    {
        FlightlogDataRecord record = initedRecords[row];

        if (record == null)
        {
          record = new FlightlogDataRecord(this, row, Logs[row]);
          initedRecords[row] = record;

          // 行が初めてアクセスされたときに、行の罫線を設定
          Worksheet.SetRangeBorders(row, 0, 1, ColumnCount, BorderPositions.Outside, RangeBorderStyle.BlackSolid);
          Worksheet.SetRangeBorders(row, 0, 1, ColumnCount, BorderPositions.InsideVertical, RangeBorderStyle.GrayDotted);
        }

        // 行データを返却
        return record;
    }

    ...
}

遅延ロードの原理および注意点

遅延ロードは、大規模なデータセットを効率的に扱うための技術です。

セルが初めてアクセスされる場合(描画、数式での参照、コードでの照会など)、データセットからデータが読み込まれます。

例えば、100万行のデータがある場合、最初に描画される30行程度のデータのみが読み込まれます。スクロールすると、必要に応じてデータが徐々に読み込まれます。

数式やセルの参照にも対応

遅延ロードは数式にも対応しています。描画されていないセルでも、数式で引用されるセルが初めてアクセスされる場合、該当セルが自動的に読み込まれます。

遅延ロードの注意点

遅延ロードは一度しか行われません。一度読み込んだワークシートのデータを削除して再度読み込む場合、読み込み完了状態がリセットされないため、遅延ロードが動作しません。このため、データの再読み込みが必要な場合は、ワークシートを再作成するなどの対応が必要です。


ページの内容は役に立ちましたか?

© 2012-2025UNVELL Inc.