MESCIUS SPREAD for ASP.NET 10.0J
個々のページ要求に対してデータをロード

個々のページ要求に対してデータをロードする場合は、状態を維持するのではなく、要求されるたびに個々のページを再作成することになります。

個々のページ要求に対してデータをロードする方法は、データセットの規模が大きく、サーバー資源の使用を最小限にとどめたい場合に有効です。

利点と欠点

個々のページ要求に対してデータをロードする利点は次のとおりです。

個々のページ要求に対してデータをロードする欠点は次のとおりです。

使用方法

ページが要求されるたびにデータをロードするには、SheetView クラスIsTrackingViewState プロパティをfalseに設定します。

サンプルコード

サンプル1

Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
    'strcon変数に適切な接続文字列を設定してください。
    Dim strcon As String = ConfigurationManager.ConnectionStrings("NorthwindConnectionString").ConnectionString
    Dim conn As New Data.SqlClient.SqlConnection(strcon)
    Dim adapt As Data.SqlClient.SqlDataAdapter
    Dim cmdText As String = "SELECT OrderID, CustomerID, EmployeeID, OrderDate, RequiredDate FROM Orders"
    Dim ds As New Data.DataSet()
    adapt = New Data.SqlClient.SqlDataAdapter(cmdText, conn)
    conn.Open()
    adapt.Fill(ds, "Orders")
    conn.Close()
    FpSpread1.Sheets(0).DataSource = ds
    '一次キーを指定し、ReadOnlyに設定
    FpSpread1.Sheets(0).DataKeyField = "OrderID"
    FpSpread1.Sheets(0).Columns(0).Locked = True
    FpSpread1.Sheets(0).IsTrackingViewState = False
End Sub

Private Sub FpSpread1_UpdateCommand(ByVal sender As System.Object, ByVal e As FarPoint.Web.Spread.SpreadCommandEventArgs) Handles FpSpread1.UpdateCommand
    'strcon変数に適切な接続文字列を設定してください。
    Dim strcon As String = ConfigurationManager.ConnectionStrings("NorthwindConnectionString").ConnectionString
    Dim conn As New Data.SqlClient.SqlConnection(strcon)
    Dim cmdText As String = "UPDATE Orders SET CustomerID = @CustomerID, EmployeeID = @EmployeeID, OrderDate = @OrderDate, RequiredDate = @RequiredDate WHERE OrderID = @OrderID"

    Dim updateCmd As Data.SqlClient.SqlCommand = New Data.SqlClient.SqlCommand(cmdText, conn)
    updateCmd.Parameters.Add(New Data.SqlClient.SqlParameter("@OrderID", Data.SqlDbType.Int, 4, "OrderID"))
    updateCmd.Parameters.Add(New Data.SqlClient.SqlParameter("@CustomerID", Data.SqlDbType.NVarChar, 5, "CustomerID"))
    updateCmd.Parameters.Add(New Data.SqlClient.SqlParameter("@EmployeeID", Data.SqlDbType.Int, 4, "EmployeeID"))
    updateCmd.Parameters.Add(New Data.SqlClient.SqlParameter("@OrderDate", Data.SqlDbType.DateTime, 8, "OrderDate"))
    updateCmd.Parameters.Add(New Data.SqlClient.SqlParameter("@RequiredDate", Data.SqlDbType.DateTime, 8, "RequiredDate"))

    Dim sv As FarPoint.Web.Spread.SheetView = e.SheetView
    Dim keyValue As String = sv.GetDataKey(e.CommandArgument)

    ' 行を検索します。
    Dim rowFlag As Boolean = False
    Dim keyCol As Integer = 0    'OrderID列
    Dim r As Integer
    For r = 0 To sv.RowCount - 1
        Dim tmp As String = sv.GetValue(r, keyCol)
        If (tmp = keyValue) Then
            rowFlag = True
            Exit For
        End If
    Next

    If Not rowFlag Then
        Return
    End If

    Dim i As Int32
    For i = 0 To sv.ColumnCount - 1
        Dim colName As String = sv.GetColumnLabel(0, i)
        If (Not e.EditValues.Item(i) Is FarPoint.Web.Spread.FpSpread.Unchanged) Then
            updateCmd.Parameters("@" & colName).Value = e.EditValues.Item(i)
        ElseIf (updateCmd.Parameters.Contains("@" & colName)) Then
            updateCmd.Parameters("@" & colName).Value = sv.GetValue(r, i)
        End If
    Next
    Try
        conn.Open()
        i = updateCmd.ExecuteNonQuery()
    Catch ex As Exception
        ' データベースのアップデートに失敗した場合
        Throw ex
    Finally
        conn.Close()
    End Try
End Sub        

サンプル2

Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
     'ページを初期化する ユーザー コードをここに挿入します。
    If Not Page.IsPostBack Then
        With FpSpread1.Pager
            .Position = FarPoint.Web.Spread.PagerPosition.TopCommandBar
            .Mode = FarPoint.Web.Spread.PagerMode.Both
        End With
    End If
    '最上行を取得します。
    Dim topRow As Integer = FpSpread1.Sheets(0).TopRow
    'データを取得します。
    SetDataModel(topRow)
End Sub

Public Sub SetDataModel(ByVal topRow As Integer)
    'strcon変数に適切な接続文字列を設定してください。
    Dim strcon As String = ConfigurationManager.ConnectionStrings("NorthwindConnectionString").ConnectionString
    Dim conn As New Data.SqlClient.SqlConnection(strcon)
    Dim adapt As Data.SqlClient.SqlDataAdapter
    Dim ps As Integer = FpSpread1.Sheets(0).PageSize
    Dim rowCount As Integer
    Dim firstID As Integer
    conn.Open()
    '全体の行数を取得
    Dim dbCmd As Data.SqlClient.SqlCommand = New Data.SqlClient.SqlCommand("SELECT COUNT(OrderID) from Orders", conn)
    rowCount = CType(dbCmd.ExecuteScalar(), Integer)
    'ID列の最小値を取得
    dbCmd = New Data.SqlClient.SqlCommand("SELECT MIN(OrderID) from Orders", conn)
    firstID = CType(dbCmd.ExecuteScalar(), Integer)
    dbCmd = New Data.SqlClient.SqlCommand("SELECT Top " & ps & " OrderID, CustomerID, EmployeeID, " & "OrderDate, RequiredDate FROM Orders Where OrderID >=" & (firstID + topRow) & " Order by OrderID")
    Dim ds As New Data.DataSet
    FpSpread1.Sheets(0).IsTrackingViewState = False
    adapt = New Data.SqlClient.SqlDataAdapter(dbCmd.CommandText, conn)
    adapt.Fill(ds, "Orders")
    Dim model As MyModel = New MyModel(ds, "Orders")
    model.TopRow = topRow
    '全体の行数を設定します。
    model.RowCount = rowCount
    'データモデルを設定します。
    FpSpread1.Sheets(0).DataModel = model
    conn.Close()
End Sub

Private Sub FpSpread1_TopRowChanged(ByVal sender As Object, ByVal e As FarPoint.Web.Spread.SpreadCommandEventArgs) Handles FpSpread1.TopRowChanged
    SetDataModel(e.SheetView.TopRow)
End Sub

カスタムデータモデルクラス

※ページに表示する以外のデータにNothingを設定します

Public Class MyModel
    Inherits FarPoint.Web.Spread.Model.BaseSheetDataModel
    Private dataset As Data.DataSet = Nothing
    Private datamember As String = String.Empty
    Private trow As Integer = 0
    Private rCount As Integer = 0
    Public Sub New(ByVal ds As Data.DataSet, ByVal dm As String)
        dataset = ds
        datamember = dm
    End Sub
    Public Overrides Function GetValue(ByVal row As Integer, ByVal col As Integer) As Object
        Dim dt As Data.DataTable = Me.GetDataTable()
        If dt Is Nothing Then
            Return Nothing
        Else
            If row < TopRow Or row >= TopRow + dt.Rows.Count Then
                Return Nothing
            Else
                Dim r As Integer = row - TopRow
                Return dt.Rows(r).Item(col)
            End If
        End If
    End Function
    Public Overrides Function IsEditable(ByVal row As Integer, ByVal col As Integer) As Boolean
        Return True
    End Function
    Public Function GetDataTable() As Data.DataTable
        If dataset Is Nothing Then
            Return Nothing
        Else
            If datamember Is Nothing Or datamember = String.Empty Then
                Return dataset.Tables(0)
            Else
                Return dataset.Tables(datamember)
            End If
        End If
    End Function
    Public Property TopRow() As Integer
        Get
            Return trow
        End Get
        Set(ByVal Value As Integer)
            trow = Value
        End Set
    End Property
    Public Overrides Property RowCount() As Integer
        Get
            Return rCount
        End Get
        Set(ByVal Value As Integer)
            rCount = Value
        End Set
    End Property
    Public Overrides Property ColumnCount() As Integer
        Get
            Dim dt As Data.DataTable = GetDataTable()
            If (dt Is Nothing) Then
                Return 0
            Else
                Return dt.Columns.Count
            End If
        End Get
        Set(ByVal Value As Integer)
        End Set
    End Property
End Class

サンプル3

この例ではより多くのコードが必要になりますが、アプリケーションの効率性はその分高くなります。ユーザーがデータを編集できるようにするには、サンプル1の様にUpdateCommand イベントをアプリケーション側で実装する必要があります。 カスタムデータモデルは、サンプル2のものと同様です。

    Private topRow As Int32 'ページ移動直前のTopRowを格納
    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        topRow = FpSpread1.Sheets(0).TopRow
        SetDataModel(topRow, topRow)
    End Sub

    Private Sub FpSpread1_TopRowChanged(ByVal sender As Object, ByVal e As FarPoint.Web.Spread.SpreadCommandEventArgs) Handles FpSpread1.TopRowChanged
        SetDataModel(topRow, e.SheetView.TopRow)
    End Sub

    Public Sub SetDataModel(ByVal oldTopRow As Integer, ByVal newTopRow As Integer)
        'strcon変数に適切な接続文字列を設定してください。
        Dim strcon As String = ConfigurationManager.ConnectionStrings("NorthwindConnectionString").ConnectionString
        Dim conn As New Data.SqlClient.SqlConnection(strcon)
        Dim adapt As Data.SqlClient.SqlDataAdapter
        Dim dbCmd As New Data.SqlClient.SqlCommand(Nothing, conn)
        Dim firstOrderID As Integer = -1
        Dim lastOrderID As Integer = -1
        If Not ViewState("lastOrderID") Is Nothing Then
            lastOrderID = ViewState("lastOrderID")
        End If
        If Not ViewState("firstOrderID") Is Nothing Then
            firstOrderID = ViewState("firstOrderID")
        End If
        Dim ps As Integer = FpSpread1.Sheets(0).PageSize
        If newTopRow > oldTopRow Then
            '[次へ] ボタン
            dbCmd.CommandText = "SELECT Top " & ps & " OrderID, CustomerID, EmployeeID, OrderDate, RequiredDate FROM Orders" & " Where OrderID >" & lastOrderID & " Order by OrderID"
        ElseIf newTopRow = oldTopRow Then
            '初回読み込み
            dbCmd.CommandText = "SELECT Top " & ps & " OrderID, CustomerID, EmployeeID, OrderDate, RequiredDate FROM Orders" & " Where OrderID >=" & firstOrderID & " Order by OrderID"
        Else
            '[戻る] ボタン
            dbCmd.CommandText = "SELECT Top " & ps & " OrderID, CustomerID, EmployeeID, OrderDate, RequiredDate FROM Orders" & " Where OrderID <" & firstOrderID & " Order by OrderID DESC"
        End If
        Dim ds As New Data.DataSet()
        FpSpread1.Sheets(0).IsTrackingViewState = False
        adapt = New Data.SqlClient.SqlDataAdapter(dbCmd.CommandText, conn)
        conn.Open()
        adapt.Fill(ds, "Orders")
        If newTopRow < oldTopRow Then
            ' Orderを保存します
            Dim tmpTable As Data.DataTable = ds.Tables("Orders").Clone()
            adapt.Fill(tmpTable)
            ds.Tables("Orders").Clear()
            Dim dr As Data.DataRow
            Dim i As Integer
            For i = 0 To tmpTable.Rows.Count - 1
                dr = tmpTable.Rows(tmpTable.Rows.Count - 1 - i)
                ds.Tables("Orders").ImportRow(dr)
            Next
        End If
        Dim model As MyModel = New MyModel(ds, "Orders")
        model.TopRow = newTopRow
        dbCmd = New Data.SqlClient.SqlCommand("select count(*) from orders", conn)
        model.RowCount = CType(dbCmd.ExecuteScalar(), Integer)
        conn.Close()
        FpSpread1.Sheets(0).DataModel = model
        ViewState("firstOrderID") = ds.Tables("Orders").Rows(0).Item("OrderID")
        Dim dtcount As Integer = ds.Tables("Orders").Rows.Count
        ViewState("lastOrderID") = ds.Tables("Orders").Rows(dtcount - 1).Item("OrderID")
    End Sub
関連トピック

 

 


© MESCIUS inc. All rights reserved.