Grade de dados:Calcular média ou soma para coluna no rodapé
Pergunta
Tenho uma grade de dados vinculada a um conjunto de dados e quero exibir o resultado médio no rodapé de uma coluna preenchida com números inteiros.
Do jeito que eu imagino, há duas maneiras em que posso pensar:
1."Use o Fonte, Lucas"
No código onde estou chamando DataGrid.DataBind(), use o método DataTable.Compute() (ou no meu caso DataSet.DataTable(0).Compute()).Por exemplo:
Dim strAverage = DataTable.Compute("Avg(ColumnName)", "")
Mas depois de ter isso, como posso inseri-lo no rodapé?
2."Vinculado para a Glória"
Usando o evento DataGrid.ItemDataBound e calculando um total em execução de cada ListItemType.Item e ListItemType.AlternatingItem, finalmente exibindo em ListItemType.Footer.Por exemplo:
Select Case e.Item.ItemType
Case ListItemType.Item, ListItemType.AlternatingItem
runningTotal += CInt(e.Item.Cells(2).Text)
Case ListItemType.Footer
e.Item.Cells(2).Text = runningTotal/DataGrid.Items.Count
End Select
Isso parece errado, além disso, eu teria que garantir que runningTotal fosse redefinido em cada DataBind.
Existe uma maneira melhor?
Solução
Não sei se algum deles é necessariamente melhor, mas dois alternar maneiras seriam:
- Percorra manualmente a tabela assim que chegar ao rodapé e calcule a partir do texto na tela
- Recupere manualmente os dados e faça o cálculo separadamente da ligação
É claro que o número 2 compensa as vantagens da vinculação de dados (supondo que é isso que você está fazendo).
Outras dicas
Obrigado Danny Smurf, sua primeira resposta me fez ver sentido.(Por que procuramos sempre essa solução mágica?).
Para referência, aqui está o que acabei fazendo:(Aviso:VB abaixo, pode não conter ponto-e-vírgula suficiente)
Case ListItemType.Footer
e.Item.Cells(0).Text = "Average"
For i As Integer = 3 To 8
Dim runningTotal As Integer = 0
For Each row As DataGridItem In DataGrid.Items
If IsNumeric(row.Cells(i).Text) Then
runningTotal += CInt(row.Cells(i).Text)
End If
Next
e.Item.Cells(i).Text = Math.Round(runningTotal / DataGrid.Items.Count, 0)
Next
End Select
Eu precisava fazer isso para várias colunas (portanto, 3 a 8), em última análise, por que estava procurando a solução mágica.