INSERT COM DATAGRIDVIEW

W8.LISBOA 25/10/2015 13:13:43
#453014
Ola pessoal,

Costumo salvar os dados de um DataGridView conforme a sub abaixo, mas se por ventura na linha 30 por exemplo, estiver uma data invalida ele salvará todas as 29 e somente mostrará a exception na 30, pois o cmd.ExecuteNonQuery() fica no dentro do laço, existe alguma maneira de salvar todas as linhas de uma unica vez, ou realmente tenho que tratar todos os dados antes de tentar o insert?

  Private Sub SalvaGridAccess()
Try
Using con As OleDbConnection = GetConnection()
con.Open()
Using cmd As New OleDbCommand
cmd.Connection = con
cmd.CommandType = CommandType.Text
cmd.CommandText = [Ô]INSERT INTO ContasApagar (IDLancamento, DataPagamento, Valor)[Ô] & _
[Ô]VALUES (@IDLancamento, @DataPagamento, @Valor)[Ô]
For i As Integer = 0 To DataGridView1.Rows.Count - 1
cmd.Parameters.Clear()
cmd.Parameters.Add([Ô]@IDLancamento[Ô], OleDbType.VarChar).Value = DataGridView1.Rows.Item(i).Cells(0).Value.ToString
cmd.Parameters.Add([Ô]@DataPagamento[Ô], OleDbType.Date).Value = DataGridView1.Rows.Item(i).Cells(1).Value
cmd.Parameters.Add([Ô]@Valor[Ô], OleDbType.Double).Value = DataGridView1.Rows.Item(i).Cells(2).Value
cmd.ExecuteNonQuery()
Next i
End Using
End Using
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
DS2T 25/10/2015 13:29:05
#453015
Esse código funcionaria bem se você tivesse certeza da validade dos dados.
O que você pode fazer, é quando a célula perder o foco, é verificar se o dado é consistente. Caso não seja, manda o foco novamente para a célula. Até o cara colocar um valor válido.

Melhor do que validar na hora de salvar. Porque isso implicaria em percorrer todas as células pra validar... e se todas forem validadas, você percorrer novamente para salvar.
Ou então criar uma transação e ir adicionando enquanto valida. E se uma der erro numa célula, você simplesmente manda um Rollback. Mas não acho essa uma boa prática. Acho um uso indevido de transactions. Mas te dei todas as opções q consegui pensar agora...

Abraços!
W8.LISBOA 25/10/2015 13:48:50
#453016
Citação:

:
Esse código funcionaria bem se você tivesse certeza da validade dos dados.
O que você pode fazer, é quando a célula perder o foco, é verificar se o dado é consistente. Caso não seja, manda o foco novamente para a célula. Até o cara colocar um valor válido.

Melhor do que validar na hora de salvar. Porque isso implicaria em percorrer todas as células pra validar... e se todas forem validadas, você percorrer novamente para salvar.
Ou então criar uma transação e ir adicionando enquanto valida. E se uma der erro numa célula, você simplesmente manda um Rollback. Mas não acho essa uma boa prática. Acho um uso indevido de transactions. Mas te dei todas as opções q consegui pensar agora...

Abraços!



DS2T,

Faço a verificação antes de adicionar valores ao datagrid, precedem de alguns textbox[ô]s, [Ô]mas com usuário não se brinca rsrsr[Ô] eles sempre vão alem da nossa imaginação, nunca tive problemas, mas é melhor prevenir.
JABA 25/10/2015 13:52:44
#453017
Se você quer garantir que nenhum registro se perca pelo caminho, então o jeito será você usar transação. Com isso, se alguma exceção for gerada no meio do caminho, os registros não serão inseridos.

Private Sub SalvaGridAccess()
Try
Using con As OleDbConnection = GetConnection()
con.Open()

[txt-color=#e80000]Dim Transacao As OleDbTransaction = con.BeginTransaction()[/txt-color]

Using cmd As New OleDbCommand
cmd.Connection = con

[txt-color=#e80000]cmd.Transaction = Transacao[/txt-color]

cmd.CommandType = CommandType.Text
cmd.CommandText = [Ô]INSERT INTO ContasApagar (IDLancamento, DataPagamento, Valor)[Ô] & _
[Ô]VALUES (@IDLancamento, @DataPagamento, @Valor)[Ô]

For i As Integer = 0 To DataGridView1.Rows.Count - 1
cmd.Parameters.Clear()
cmd.Parameters.Add([Ô]@IDLancamento[Ô], OleDbType.VarChar).Value = DataGridView1.Rows.Item(i).Cells(0).Value.ToString
cmd.Parameters.Add([Ô]@DataPagamento[Ô], OleDbType.Date).Value = DataGridView1.Rows.Item(i).Cells(1).Value
cmd.Parameters.Add([Ô]@Valor[Ô], OleDbType.Double).Value = DataGridView1.Rows.Item(i).Cells(2).Value
cmd.ExecuteNonQuery()
Next i

[txt-color=#e80000]Transacao.Commit()[/txt-color]

End Using
End Using
Catch ex As Exception
[txt-color=#e80000]Transacao.Rollback()[/txt-color]
MessageBox.Show(ex.Message)
End Try
End Sub

W8.LISBOA 25/10/2015 14:04:20
#453018
Obrigado JABA,

Conforme o amigo DS2T disse anteriormente, qual a desvantagem ou vantagem de usar transaction neste caso?
JABA 25/10/2015 14:07:45
#453020
Resposta escolhida
Não vejo isso por uma questão de vantagem ou desvantagem, mas, sim, por necessidade. Se você quer garantir que todos esses dados estejam presentes na sua base de dados, então só lhe resta usar transação para isso. Se você fizer isso de outra forma e acabar a energia no meio das operações, somente alguns registros serão salvos, enquanto que os outros serão perdidos.
W8.LISBOA 25/10/2015 14:30:54
#453021
JABA, entendido, também tinha pensado nessa hipótese da energia.

Tentando colocar em pratica o seu código, estou com um erro na visibilidade da variável Transacao no bloco da exception, acredito que seja porque fecho o Using antes. Alguma sugestão?
DS2T 25/10/2015 15:03:09
#453023
W8-LISBOA,


Nesse caso específico, não recomendei o uso de Transaction porque você estava preocupado com as informações de entrada do usuário gerarem erro. Transações foram feitas para garantir a total persistência, caso contrário, nenhuma operação será contabilizada. Se adequaria a sua necessidade, se sua preocupação não fosse somente a entrada errada do usuário. Se fosse preocupação por ser uma operação demorada e estar com medo da internet cair, o banco ficar ocioso, você não ter controle dos dados de entrada, etc... Recomendaria o uso do Transaction, sim.

Só não acho a melhor maneira de tratar algo que deveria ser tratado antes. Quando você vai persistir os dados no banco de dados, você já teria que ter certeza da validade deles.
Vai dar certo com Transaction? Dá sim... E por ser uma lista, é até recomendado. O que não acho certo é deixar deixar a transação como substituto de uma boa validação de dados. Até porque você perde o controle da sua aplicação.

Abraços!
JABA 25/10/2015 15:41:04
#453025
Tente assim pra ver se vai:

Private Sub SalvaGridAccess()
Try
dim con As OleDbConnection = GetConnection()
con.Open()

[txt-color=#e80000]Dim Transacao As OleDbTransaction = con.BeginTransaction()[/txt-color]

dim cmd As New OleDbCommand
cmd.Connection = con

[txt-color=#e80000]cmd.Transaction = Transacao[/txt-color]

cmd.CommandType = CommandType.Text
cmd.CommandText = [Ô]INSERT INTO ContasApagar (IDLancamento, DataPagamento, Valor)[Ô] & _
[Ô]VALUES (@IDLancamento, @DataPagamento, @Valor)[Ô]

For i As Integer = 0 To DataGridView1.Rows.Count - 1
cmd.Parameters.Clear()
cmd.Parameters.Add([Ô]@IDLancamento[Ô], OleDbType.VarChar).Value = DataGridView1.Rows.Item(i).Cells(0).Value.ToString
cmd.Parameters.Add([Ô]@DataPagamento[Ô], OleDbType.Date).Value = DataGridView1.Rows.Item(i).Cells(1).Value
cmd.Parameters.Add([Ô]@Valor[Ô], OleDbType.Double).Value = DataGridView1.Rows.Item(i).Cells(2).Value
cmd.ExecuteNonQuery()
Next i

[txt-color=#e80000]Transacao.Commit()[/txt-color]

Catch ex As Exception
[txt-color=#e80000]Transacao.Rollback()[/txt-color]
MessageBox.Show(ex.Message)
[txt-color=#e80000]Finally[/txt-color]
[txt-color=#e80000]con.Close()[/txt-color]
End Try
End Sub
ACCIOLLY 25/10/2015 16:06:06
#453026
olá W8-LISBOA,
Deixa eu ver se entendi,
O que vc quer é salvar todos os dados com apenas um comando SQL?
Bom na verdade não tem mesmo! rsrsrsr.
O que voce pode fazer também, até pra dar outra alternativa, é gerar todos os SQL[ô]s de uma só vez. Pois sabemos que se quizermos fazer vários inserts de uma só vez, é só separarmos cada um por ponto e vírgula [Ô];[Ô] portanto ponto e vírgula é o final de um comando sql que pula pro próximo. Repare:

Dim SQL AS String = [Ô]INSERT INTO clientes(nome,dn,endereco) VALUES([ô]Joao[ô],[ô]23/08/1978[ô],[ô]Rua 1[ô]);INSERT INTO clientes(nome,dn,endereco) VALUES([ô]Maria[ô],[ô]23/08/1978[ô],[ô]Rua 13[ô]);INSERT INTO clientes(nome,dn,endereco) VALUES([ô]Rosa[ô],[ô]23/08/1978[ô],[ô]Rua 17[ô]);[Ô]
cmd.CommandText = SQL
cmd.ExecuteNonQuery()


Com isso seus dados seriam executados em um unico comando SQL. Daí pra vc montar esse SQL é só fazendo um loop também

valeu
W8.LISBOA 25/10/2015 16:06:19
#453027
Citação:

:
Tente assim pra ver se vai:

Private Sub SalvaGridAccess()
Try
dim con As OleDbConnection = GetConnection()
con.Open()

[txt-color=#e80000]Dim Transacao As OleDbTransaction = con.BeginTransaction()[/txt-color]

dim cmd As New OleDbCommand
cmd.Connection = con

[txt-color=#e80000]cmd.Transaction = Transacao[/txt-color]

cmd.CommandType = CommandType.Text
cmd.CommandText = [Ô]INSERT INTO ContasApagar (IDLancamento, DataPagamento, Valor)[Ô] & _
[Ô]VALUES (@IDLancamento, @DataPagamento, @Valor)[Ô]

For i As Integer = 0 To DataGridView1.Rows.Count - 1
cmd.Parameters.Clear()
cmd.Parameters.Add([Ô]@IDLancamento[Ô], OleDbType.VarChar).Value = DataGridView1.Rows.Item(i).Cells(0).Value.ToString
cmd.Parameters.Add([Ô]@DataPagamento[Ô], OleDbType.Date).Value = DataGridView1.Rows.Item(i).Cells(1).Value
cmd.Parameters.Add([Ô]@Valor[Ô], OleDbType.Double).Value = DataGridView1.Rows.Item(i).Cells(2).Value
cmd.ExecuteNonQuery()
Next i

[txt-color=#e80000]Transacao.Commit()[/txt-color]

Catch ex As Exception
[txt-color=#e80000]Transacao.Rollback()[/txt-color]
MessageBox.Show(ex.Message)
[txt-color=#e80000]Finally[/txt-color]
[txt-color=#e80000]con.Close()[/txt-color]
End Try
End Sub



Ainda não...

no
  Catch ex As Exception
Transacao.Rollback()
MessageBox.Show(ex.Message)
Finally
con.Close()
End Try

Transacao.Rollback() e con.Close()[Ô]diz não está declarado, pode estar inacessível devido ao seu nível de proteção[Ô]
Página 1 de 2 [18 registro(s)]
Tópico encerrado , respostas não são mais permitidas