1. Este site usa cookies. Ao continuar a usar este site está a concordar com o nosso uso de cookies. Saber Mais.

Help em VB 2008 || Datagridview_cellvaluechanged

Discussão em 'Programação' iniciada por Soldi3r^^, 13 de Janeiro de 2008. (Respostas: 17; Visualizações: 1580)

  1. Soldi3r^^

    Soldi3r^^ Power Member

    Boas pessoal.. Tenho um datagridview que ao meter o código do produto ele vai buscar o resto das informações e adiciona, como por exemplo, preço,iva,etc..

    O que se passa é que mete o primeiro e está tudo OK. mas se meto noutra linha outro ele retira-me o primeiro e simplesmente fica o segundo que pus...

    Ora aqui está o código:

    Código:
    Private Sub DataGridView1_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged
            Dim conn As New MySqlConnection
            Dim myCommand As New MySqlCommand
            Dim myAdapter As New MySqlDataAdapter
            Dim myData As New DataTable
            Dim SQL As String
    
    
            'Toma Valores
    
            SQL = "SELECT p.`codigo`, p.`nome`, p.`iva`, p.`preco` FROM produtos p WHERE p.`codigo` =  " & DataGridView1.CurrentCell.Value & ";"
    
            'Dados Login
            conn.ConnectionString = "server=" & server & ";" _
                & "port=3306" & ";" _
                & "user id=" & user & ";" _
                & "password=" & pass & ";" _
                & "database=dados"
    
            Try
    
                conn.Open()
    
                Try
    
                    myCommand.Connection = conn
                    myCommand.CommandText = SQL
                    myAdapter.SelectCommand = myCommand
                    myAdapter.Fill(myData)
                    DataGridView1.DataSource = myData
    
    
    
    
                Catch myerro As MySqlException
                    MsgBox("Erro de leitura no banco de dados : " & myerro.Message)
                End Try
                conn.Close()
            Catch myerro As MySqlException
                MessageBox.Show("Erro ao conectar com o Banco de dados : " & myerro.Message)
            Finally
                conn.Dispose()
            End Try
    
        End Sub
    
    Penso que o erro está no "myAdapter.Fill(myData)" no entanto não consigo arranjar outro comando.. já tentei o update e também não dá..

    waiting for help ^^

    cumps.
     
    Última edição: 1 de Maio de 2008
  2. Soldi3r^^

    Soldi3r^^ Power Member

    Ninguêm? :/
     
  3. mOrSa

    mOrSa Power Member

    E se em vez do mydata ser do tipo DataTable ser do tipo Dataset ??
    Código:
            Dim myData As New DataTable 
    Passa para:          Dim myData As New Dataset
    Posteriormente deves substituir esta linha

    Código:
                     DataGridView1.DataSource = myData
    
    por                  DataGridView1.DataSource = myData.Tables(0)
    Experimenta. Não garanto que funcione mas saltou-me isso à vista.... espero ter ajudado

    1abraço!
     
  4. Soldi3r^^

    Soldi3r^^ Power Member

    faz o mesmo :/ obrigado de qualquer maneira.. mais sugestões são aceites :)
     
  5. mOrSa

    mOrSa Power Member

    Já testaste a query no MySQL? i.e., sem ser via VB? Até pk com "DataGridView1.CurrentCell.Value" eu já tive valores... (passava-me o objecto e não o valor... é estúpido :P ).

    O que costumo fazer é usar o debug e o watch. Colocas breakpoints e faz instrução a instrução e vê principalmente o valor da query. Se ele não te mostra resultados pode ser precisamente por essa situação... a query está com um erro não "aparente".

    Depois reparei que tu no final fazes -> DataGridView1.DataSource = myData <- ou seja ele volta a actualizar o dados... será que tens tempo para ver o dados?

    Há aí qq coisa que me parece não estar "correcta". Desculpa n poder ajudar!

    1abraço!
     
  6. Soldi3r^^

    Soldi3r^^ Power Member

    Ele mostra os resultados, tipo eu meto o código do produto, por exemplo 1, e ele obtem o resto dos dados e coloca nas outras colunas da mesma linha.

    O problema mesmo é depois ao inserir outro registo, pois tá lá o primeiro, meto um 2 e ele apaga o outro e fica apenas o 2.. isto penso eu que seja por causa do "DataGridView1.DataSource = myData" só que não sei de outro comando para isto dar..
     
  7. mOrSa

    mOrSa Power Member

    Posta aí um screenshot que eu n estou a ver a cena! :P hehehe

    abraço
     
  8. Soldi3r^^

    Soldi3r^^ Power Member

    ora aqui vão eles ^^

    [​IMG][​IMG][​IMG][​IMG]

    Na primeira imagem, insiro o código do produto, depois na segunda já ele foi buscar o resto dos valores.
    Na 3ª vou inserir o segundo registo, metendo o código de produto 2.
    E na 4ª eis o que acontece... fica apenas o 2 registo e o primeiro, foi dar uma volta :/

    lol

    cumps.
     
  9. mOrSa

    mOrSa Power Member

    Ora bem:

    Segundo o que percebi, fazes uma "factura" e em cada linha que "terminas" ele automaticamente grava o produto, certo? Se isto é verdade podem acontecer várias coisas:
    - se tiveres um sistema multi-utilizador corres o risco de a factura 1 não estar correcta.
    - vários utilizadores têm o mm número de documento
    ... por isso sugiro que não vás por aí.

    Na minha ideia, será melhor preencheres toda a Datagrid de detalhes e posteriormente guardar esses valores na Base de Dados e só, nesse instante, atribuires o correcto valor do n.º da factura.

    Se queres obter a descrição do produto após teres digitado o código do produto sugiro também que o faças de outra forma: fazes a query somente quando mudas de coluna na tabela. com essa query obtens os valores do produto do tipo:

    Código:
    SELECT descricao, preco_venda, desconto, id_tabela_iva FROM Produto WHERE cod_produto = @cod_produto
    Posto isto obtens os valores num dataset (ds, por exemplo), e terás em ds.Tables(0).Rows(0) (objecto DataRow) todos os valores que pediste na query.

    ds.Tables(0).Rows(0).Item("descricao") terá o valor da descricao e só tens que o colocar na célula certa!

    Código:
    Datagridview1.Cell("coluna_descricao", linha).Value = ds.Tables(0).Rows(0).Item("descricao")
    podes fazer o mesmo para o preço, desconto, iva... etc... o valor da variável linha pode advir de dois sítios distintos:
    - do DataGridView1.CurrentCell.RowIndex ou
    - do e.RowIndex no caso de utilizares um dos eventos da Datagrid como o CellChanged (acho que este existe! :P )

    O que estás a fazer é um select de algo que ainda não existe e a devolver as linhas. A menos que no final de cada linha a insiras na BD isso nunca irá resultar. Ainda assim são capaz de surgir outros problemas.

    Espero ter ajudado!
    1abraço!
     
  10. Soldi3r^^

    Soldi3r^^ Power Member

    Não propriamente, tenho a factura, Insiro o código do produto e ele executa a query e poem tudo no sitio. No entanto não guarda nada ainda. Sim tinha ali o número de factura e ainda bem que me lembras-te do problema de multi utilizador que me tinha esquecido, e já alterei, apenas atribui o número de factura ao concluir.
    Quanto a esta parte:
    é mesmo assim que tenho, ao mudar de coluna/campo ele vai buscar os dados.

    Se puderes dar uma ajudinha no dataset.. é que não percebi muito bem essa parte..

    Nunca mexi em Dataset, mas também á uma primeira vêz para tudo, vou estudar o caso e muito obrigado pela ajuda ;)


    cumps

    -edit-

    depois de ir buscar os dados do produto ele vai para o dataset e depois passo os valores para o datagrid? é isso? lol..

    Estive a ver e o .Cell em Datagridview1.Cell não existe :P tou á procura de outra maneira, mas acho que já percebi :)

    -edit2-

    Tentei o Datagridview.item('coluna','linha') = DataSet1.Tables(0).Rows(0).Item("nome")
    mas não consigo, pois dá erro ao passar o valor de String(DataSet1.Tables(0).Rows(0).Item("nome") ) para DataGridViewCell (Datagridview.item('coluna','linha') ) :/
     
    Última edição: 14 de Janeiro de 2008
  11. mOrSa

    mOrSa Power Member

    Ora bem... não sei se a explicação é a mais correcta mas é como encaro os dataset's (alguém que me corrija se estiver errado) mas cá vai:

    Uma DataTable é uma tabela de dados, simples, tal como se desenha uma tabela no Excel, por exemplo. Um Dataset é nada mais que um conjunto de tabelas com capacidades de "serialização" (convertes um Dataset para XML num tirinho :) ).

    Ok. Vamos esquecer o Dataset! E usar a Datatable!

    Após teres feito a query em vez de direccionares o teu datasource da datagrid para todos os resultados usas os resultados [pegando no teu código] em separado:

    (...)
    myAdapter.Fill(myData)
    ' utilizar a descricao

    Dim desc As String
    Dim preco as Double

    desc = myData.Rows(0).Item("descricao").ToString()
    preco = myData.Rows(0).Item("preco").ToString()

    Espero que estejas a perceber a ideia... se precisares de alguma coisa usa o messenger que eu dou-te uma ajuda. Mesmo que seja à noite!

    1Abraço!

    -- edit ---
    Eu usei assim

    Dim ds_t as New Dataset
    (...)
    DataGridView1.Item(DataGridView1.Columns("descricao").Index, IndiceLinha).Value = ds_t.Tables(0).Rows(0).Item("descricao")
     
    Última edição: 14 de Janeiro de 2008
  12. Soldi3r^^

    Soldi3r^^ Power Member

    Já consegui. Muito obrigado.

    Já agora aqui fica a solução:

    Código:
    Private Sub DataGridView1_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged
            Dim conn As New MySqlConnection
            Dim myCommand As New MySqlCommand
            Dim myAdapter As New MySqlDataAdapter
            Dim myData As New DataTable
            Dim SQL As String
    
            'Toma Valores
    
            SQL = "SELECT p.`codigo`, p.`nome`, p.`iva`, p.`preco` FROM produtos p WHERE p.`codigo` =  " & DataGridView1.CurrentCell.Value & ";"
    
            'Dados Login
            conn.ConnectionString = "server=" & server & ";" _
                & "port=3306" & ";" _
                & "user id=" & user & ";" _
                & "password=" & pass & ";" _
                & "database=dados"
    
            Try
    
                conn.Open()
    
                Try
    
                    myCommand.Connection = conn
                    myCommand.CommandText = SQL
                    myAdapter.SelectCommand = myCommand
                    myAdapter.Fill(myData)
                    If myData.Rows.Count = 0 Then
                        MessageBox.Show("Produto não encontrado", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error)
                    Else
                        Dim dataset1 As New DataSet
                        dataset1.Tables.Add(myData)
                        DataGridView1.Item(DataGridView1.Columns(1).Index, DataGridView1.CurrentCell.RowIndex).Value = dataset1.Tables(0).Rows(0).Item(1)
                        DataGridView1.Item(DataGridView1.Columns(2).Index, DataGridView1.CurrentCell.RowIndex).Value = dataset1.Tables(0).Rows(0).Item(3)
                        DataGridView1.Item(DataGridView1.Columns(3).Index, DataGridView1.CurrentCell.RowIndex).Value = dataset1.Tables(0).Rows(0).Item(2)
                    End If
    
                Catch myerro As MySqlException
                    MsgBox("Erro de leitura no banco de dados : " & myerro.Message)
                End Try
                conn.Close()
            Catch myerro As MySqlException
                MessageBox.Show("Erro ao conectar com o Banco de dados : " & myerro.Message)
            Finally
                conn.Dispose()
            End Try
        End Sub
    
    cumps.
     
    Última edição: 14 de Janeiro de 2008
  13. Soldi3r^^

    Soldi3r^^ Power Member

    Novo prolema..

    Bem aproveitando o meu tópico, preciso de ajuda numa outra coisa +ou- relacionada com essa...

    como podem reparar estou a utilizar o "DataGridView1_CellValueChanged" existe alguma possibilidade de apenas executar isso se for alterado o valor da célula 1,1 por exemplo? ou um outro evento? é que é o seguinte..

    quero que quando seja introduzido um código de produto igual no datagrid ele automaticamente apague essa linha onde se inseriu, e na linha onde já tem o código existente que aumente a quantidade, removendo assim registos duplicados no datagrid..

    sugestões?

    Cumps.

    -edit-

    Aspecto do datagrid actualmente:

    [​IMG]

    -edit2-

    Quanto á questão do controlo consigo fazer.. o problema é que me vai fazer overflow.. visto sempre que alterar um valor de uma célula ele executar aquele procedimento...

    Eis o código do controlo:

    Código:
        Private Sub verifica_codigo()
    
            codigo = DataGridView1.CurrentCell.Value.ToString
            MessageBox.Show(codigo)
            If array_controlo(DataGridView1.CurrentCell.RowIndex) = "" Then
                array_controlo(DataGridView1.CurrentCell.RowIndex) = codigo
            End If
            For i = 0 To array_controlo.Length - 1
                'correcto até aqui...
                If array_controlo(i) = codigo Then
                    If DataGridView1.Item(4, i).Value.ToString = "" Then
                    Else
                        DataGridView1.Item(4, i).Value += 1
                    End If
                End If
            Next
        End Sub
    
    a messagebox foi precisamente para controlar quantas vezes executava... por isso ignorem..
     
    Última edição: 1 de Maio de 2008
  14. jpaulino

    jpaulino Power Member

    Desculpa lá ... dá lá um exemplo que eu não consegui enterder muito bem o que queres.
     
  15. Soldi3r^^

    Soldi3r^^ Power Member


    Tipo,

    tenho o datagrid e meto um produto com o código 1... ele automaticamente preenche os campos com o dado do produto(nome, preço,etc..) e depois meto a quantidade 1 e ele mete o valor correspondente, consoante a quantidade.

    depois meto por exemplo outro produto com o código 2, e a mesmo coisa que o outro..
    mas agora se meter outro produto com o código 1 ou 2, eu quero que ele elimine essa linha que foi adicionada, e que na respectiva linha do código adicione +1 na quantidade... até aqui tudo bem.

    mas o problema, é que como estou a usar o datagridview_cellvaluechanged, ele está sempre a executar aquilo quando um valor muda... ou seja.. o código muda a quantidade para 2, e ele volta a repetir tudo.. e está sempre assim, provocando um overflow..

    O que queria era em vez de ele executar o cellvaluechangedm, sempre que qualquer valor no datagrid é alterado, apenas se altera-se o valor da célula (1,1) por exemplo...

    Cumps.
     
  16. jpaulino

    jpaulino Power Member

    Hummm, já entendi!

    Usa uma variável boolean como private e no momento em que vais correr a função coloca-a a true e no final da função a false. Depois só tens de verificar no evento CellValueChanged se a variável estiver a true não faz nada.
     
  17. jpaulino

    jpaulino Power Member

    Se quiseres algo mais pro diz. Dá um pouco mais trabalho mas também se faz.
     
  18. Soldi3r^^

    Soldi3r^^ Power Member

    Muito obrigado pela explicação...

    é sempre incrível como coisas difíceis uma pessoa faz na boa.. e as mais fáceis falha sempre algo.. nunca me veio à cabeça essa parte.. até veio mas foi para outra função não para ali.. lol...
     

Partilhar esta Página