none
VB 2012 - Pesquisa no Datagridview na tabela Sql Server Compact (Cadastro.sdf) RRS feed

  • Pergunta

  • Em meu aplicativo desenvolvido em VISUAL STUDIO EXPRESS 2012 tenho um formulário com um DataGridView e um Textbox para pesquisa.

    Gostaria que meu Textbox efetuase a pesquisa dos nome cadastrados com acento ou sem acento na tabela, Tais como:

    Quando digitado qualquer nome, indiferentemente de ter sido escrito com acento, retornasse na pesquisa os nomes que estão no cadastro com acento e sem acento. Ex: Digito JOÃO etc...

    E no DataGridView fosse listado:

    FRANCISCO JOÃO DA SILVA

    FRANCISCO JOÃO DA SILVA

    MARCOS ANTÔNIO JOAO DA SILVA.

    MARCOS ANTONIO JOÃO DA SILVA

    Agradeço desde já pela cooperação.
    sexta-feira, 18 de março de 2016 15:03

Todas as Respostas

  • Você pode usar a função do Serge Wautier para normalizar a string, retirando os acentos:

    static string RemoveDiacritics(string text)
    {
      return string.Concat( 
          text.Normalize(NormalizationForm.FormD)
          .Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch)!=
                                        UnicodeCategory.NonSpacingMark)
        ).Normalize(NormalizationForm.FormC);
    }

    Ou pode fazer desta forma:

    string s1 = "HEllO";
    string s2 = "héLLo";
    
    if (String.Compare(s1, s2, CultureInfo.CurrentCulture, CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase) == 0)
    {
        // Strings são iguais
    }

    Dê uma olhada em:

    Como comparar cadeias de caracteres (Guia de Programação em C#)

    Att,


    Antero Marques

    • Marcado como Resposta FJSobreira sexta-feira, 18 de março de 2016 15:50
    • Não Marcado como Resposta FJSobreira sexta-feira, 18 de março de 2016 15:53
    sexta-feira, 18 de março de 2016 15:35
  • Através de string, conforme orientação acima, não resolve o problema uma vez que a tabela está com mais de 8.000 registros, contendo centenas de nomes com ACENTO. O que resolveria seria uma função para iguinorar o o acento quando fosse efetuada a pesquisa.  O Cliente não aceita fazer o cadastro sem acento!
    sexta-feira, 18 de março de 2016 16:00
  • Sobreira,

    Se você monta uma string de comando para passar para o banco, pode setar um collation Accent Insensitive na comparação, exemplo:

    select * from (select 'Hélió' as Nome) t where  nome collate Latin1_General_CI_AI = 'helio'

    No caso, você pode usar o collation na string:

    var string = "select * from tabela where Lower(nome) collate Latin1_General_AI_CI = @nome";

    e o parâmetro você trata com a função RemoveDiacritics, setando lower na string.

    Att,


    Antero Marques

    sexta-feira, 18 de março de 2016 16:27
  • Não consegui sucesso com a orientação acima. Não soube montar o código.

    ABAIXO TRANSCREVO OS CÓDIGOS DO MEU FORM QUE LISTA POR QUALQUER PARTE DO NOME PESQUISADO. (Palavras com acento só serão mostradas os cadastro que tenham acento).

    *************************************************************************************

        Private Sub Pesquisa_KeyDown(sender As Object, e As KeyEventArgs) Handles Pesquisa.KeyDown
            '*************FUNCIONA PESQUISANDO QUALQUER PARTE DO NOME
            Dim texto As String = Nothing
            If Pesquisa.Text <> String.Empty Then
                For Each row As DataGridViewRow In DataGridView1.Rows
                    For Each celula As DataGridViewCell In DataGridView1.Rows(row.Index).Cells
                        If celula.ColumnIndex = 2 Then
                            ' RS.Filter = "[Nome] like '%" & Me.Pesquisa.Text & "%'"
                            texto = celula.Value.ToString
                            If texto.Contains(Pesquisa.Text) Then
                                  DataGridView1.CurrentCell = celula
                                Exit Sub
                            End If
                        End If
                    Next
                Next
            End If

        End Sub
       

    Private Sub Pesquisa_TextChanged(sender As Object, e As EventArgs) Handles Pesquisa.TextChanged
            CarregaGrid()
            'Contagem.Text = DataGridView1.RowCount
            Contagem.Text = DataGridView1.RowCount
        End Sub
     

       Private Sub CarregaGrid()
            Dim connString As String = "Data Source=|DataDirectory|\Bd_CADASTRO.sdf"
            Dim myConnection As SqlCeConnection = New SqlCeConnection()
            myConnection.ConnectionString = connString
            Dim da As New SqlCeDataAdapter("select * from CADASTRO where Nome like '%" & Pesquisa.Text & "%'  OR Endereço like '%" & Pesquisa.Text & "%' order by Nome", connString)
            ' create a new dataset
            Dim ds As DataSet = New DataSet()
            ' fill dataset
            da.Fill(ds, "CADASTRO")
            datagridconfig()
            DataGridView1.DataSource = ds.Tables("CADASTRO")
            DataGridView1.Refresh()
            Contagem.Text = DataGridView1.RowCount
        End Sub
     

       Private Sub datagridconfig()
            DataGridView1.AutoGenerateColumns = False
            DataGridView1.Columns.Clear()
            DataGridView1.Columns.Add("CADASTRO", "CIDADE")
            DataGridView1.Columns.Add("CADASTRO", "NOME")
            DataGridView1.Columns.Add("MISICAS", "ENDEREÇO")
            '************************************************
            DataGridView1.Columns(0).DataPropertyName = "CIDADE"
            DataGridView1.Columns(1).DataPropertyName = "Nome"
            DataGridView1.Columns(2).DataPropertyName = "Endereçor"
            '*****************FINAL DAS COLUNAS
            DataGridView1.Columns(0).Width = 310
            DataGridView1.Columns(1).Width = 320
            DataGridView1.Columns(2).Width = 190
            'Alinhar Linha do DataGridview
            'DataGridView1.Columns(2).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
            ' DataGridView1.Columns(1).DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
            '***********OCULTANDO AS COLUNAS********************************************
            DataGridView1.Columns(0).Visible = False
        End Sub
     

       Private Sub errorcheck()
            If Err.Number <> 0 Then
                MsgBox("Não foi possível acessar o banco de dados.")
                Exit Sub
            Else
                'MsgBox("The Northwind database was opened successfully.")
            End If
        End Sub
        Private Sub SAIR_Click(sender As Object, e As EventArgs) Handles SAIR.Click
            Me.Close()
        End Sub

    sábado, 19 de março de 2016 01:39
  • Para fazer algo parecido com sua estrutura, eu fiz um projeto funcional onde há uma pesquisa no Text Change do TextBox e traz todos os valores independente de acentuação.

        Dim Constr As String =
                ConfigurationManager.ConnectionStrings("BancoLocal").ConnectionString
        Dim _con As SqlConnection = New SqlConnection(Constr)
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            CarregaGrid(Pesquisa.Text)
        End Sub
    
        Private Sub CarregaGrid(pesquisa As String)
            Try
                _con.Open()
                Dim cmd As SqlCommand = New SqlCommand("SELECT * FROM CADASTRO where ([nome] collate Latin1_General_CI_AI like  '%' + @valor + '%') or ([endereço] collate Latin1_General_CI_AI like '%' + @valor + '%')", _con)
                cmd.Parameters.Add("valor", SqlDbType.VarChar, 80).Value = pesquisa
                Dim data As SqlDataAdapter = New SqlDataAdapter(cmd)
                Dim dbset As DataSet = New DataSet()
                data.Fill(dbset, "CADASTRO")
                Dim c = dbset.Tables("CADASTRO").Rows.Count
                If (c > 0) Then
                    DataGridView1.DataSource = dbset
                    DataGridView1.DataMember = "CADASTRO"
                    DataGridView1.Refresh()
                End If
    
            Catch ex As Exception
                MessageBox.Show(ex.Message)
                MessageBox.Show("Stack Trace: " & vbCrLf & ex.StackTrace)
            Finally
                _con.Close()
            End Try
        End Sub
    
        Private Sub Pesquisa_TextChanged(sender As Object, e As EventArgs) Handles Pesquisa.TextChanged
            CarregaGrid(Pesquisa.Text)
        End Sub

    Espero que te ajude a compreender.

    Att,


    Antero Marques


    sábado, 19 de março de 2016 05:10
  • Fiz como orientado, porém apresentou o erro "ConfigurationManager" não está declarado. Ele pode ser inacessível devido ao seu nível de proteção.

    INFELISMENTE NÃO CONSEGUI, DEPOIS DE INÚMERAS PESQUISAS, SOLUCIONAR O PROBLEMA.


    sábado, 19 de março de 2016 15:35
  • Adicione a referência da DLL manualmente que isso se resolve.

    Dentro de assemlies:

    System.Configuration

    Mas você não precisa mudar como faz acesso a base, concentre-se só no método de carregar a o grid.


    Antero Marques



    sábado, 19 de março de 2016 16:48
  • APÓS INSTALAR A DLL, FIZ UM TESTE ASSIM:

        Private Sub CarregaGrid(pesquisa As String)
            Dim Constr As String = ConfigurationManager.ConnectionStrings("Data Source=|DataDirectory|\Bd_Músicas.sdf").ConnectionString
            Dim _con As SqlConnection = New SqlConnection(Constr)
            Try
                _con.Open()
                Dim cmd As SqlCommand = New SqlCommand("SELECT * FROM MISICAS where ([NOM_CANTOR] collate Latin1_General_CI_AI like  '%' + @valor + '%') or ([NOM_MUS] collate Latin1_General_CI_AI like '%' + @valor + '%')", _con)
                cmd.Parameters.Add("valor", SqlDbType.VarChar, 80).Value = Pesquisa
                Dim data As SqlDataAdapter = New SqlDataAdapter(cmd)
                Dim dbset As DataSet = New DataSet()
                data.Fill(dbset, "MISICAS")
                Dim c = dbset.Tables("MISICAS").Rows.Count
                If (c > 0) Then
                    DataGridView1.DataSource = dbset
                    DataGridView1.DataMember = "MISICAS"
                    DataGridView1.Refresh()
                End If

            Catch ex As Exception
                MessageBox.Show(ex.Message)
                MessageBox.Show("Stack Trace: " & vbCrLf & ex.StackTrace)
            Finally
                _con.Close()
            End Try
        End Sub

    PORÉM QUANDO EXECUTO O SISTEMA PARA OPERAR ESTE TRAVA COM A SEGUINTE MENSAGEM:

    Ocorreu uma exceção sem tratamento do tipo 'System.NullReferenceException' em TESTE.EXE

    Focando o ponteiro marcando com erro "        Dim Constr As String = ConfigurationManager.ConnectionStrings("Data Source=|DataDirectory|\Bd_Músicas.sdf").ConnectionString"

    sábado, 19 de março de 2016 21:31
  • Após várias tentativas de fazer funcionar, infelismente, não fui capaz de desenvolver a pesquisa dentro do esperado. Agradeço a todos aqueles que buscaram alguma forma de ajuda. Principalmente o Antero. Caso algum colega desenvolva esta aplicação e queira enviar o modelo, favor direcionar um para o e_mail f.j.sobreira@bol.com.br que será muito bem vindo.
    domingo, 20 de março de 2016 15:04
  • NA LINHA "Dim cmd As SqlCommand = New SqlCommand("SELECT * FROM MISICAS where ([NOM_CANTOR] collate Latin1_General_CI_AI like  '%' + @valor + '%') or ([NOM_MUS] collate Latin1_General_CI_AI like '%' + @valor + '%')", _con)" tá dando erro em _con.

    A mensagem de erro e:

    1    Valor de tipo 'System.Data.SqlServerCe.SqlCeConnection' não pode ser convertido para 'System.Data.SqlClient.SqlConnection'.

    domingo, 20 de março de 2016 21:26
  • Após tanta atenção e busca em ajuda, agradeço, e muito ao Antero.

    Agora o erro está em "Dim data As SqlDataAdapter = New SqlDataAdapter(cmd)" - MENSAGEM DE ERRO:

    1    Valor de tipo 'System.Data.SqlServerCe.SqlCeCommand' não pode ser convertido para 'System.Data.SqlClient.SqlCommand'.

    domingo, 20 de março de 2016 23:06
  • Que nada sobreira...rsrs.. normal..

    É que eu fiz para o sql server enterprise e você para o compact edition.. deixa eu converter tudo e te passo.


    Antero Marques

    domingo, 20 de março de 2016 23:18
  • Agradeço, e muito todo o empenho demonstrado na solução deste problema. OBRIGADO!
    domingo, 20 de março de 2016 23:24
  • Por hora, teste desta forma, pois não tenho o Compact Edtion aqui.
    Private Sub CarregaGrid(pesquisa As String)
    	Dim Constr As String = "Data Source=|DataDirectory|\Bd_CADASTRO.sdf"
            Dim _con As SqlCeConnection = New SqlCeConnection(Constr)
            Try
                _con.Open()
                Dim cmd As SqlCeCommand = New SqlCeCommand("SELECT * FROM MISICAS where ([NOM_CANTOR] collate Latin1_General_CI_AI like  '%' + @valor + '%') or ([NOM_MUS] collate Latin1_General_CI_AI like '%' + @valor + '%')", _con)
                cmd.Parameters.Add("valor", SqlDbType.VarChar, 80).Value = Pesquisa
                Dim data As SqlCeDataAdapter = New SqlCeDataAdapter(cmd)
                Dim dbset As DataSet = New DataSet()
                data.Fill(dbset, "MISICAS")
                Dim c = dbset.Tables("MISICAS").Rows.Count
                If (c > 0) Then
                    DataGridView1.DataSource = dbset
                    DataGridView1.DataMember = "MISICAS"
                    DataGridView1.Refresh()
                End If
    
            Catch ex As Exception
                MessageBox.Show(ex.Message)
                MessageBox.Show("Stack Trace: " & vbCrLf & ex.StackTrace)
            Finally
                _con.Close()
            End Try
        End Sub
    
    Private Sub Pesquisa_TextChanged(sender As Object, e As EventArgs) Handles Pesquisa.TextChanged
            CarregaGrid(Pesquisa.Text)
    End Sub


    Antero Marques



    segunda-feira, 21 de março de 2016 00:07
  • Continua o erro na lina "Dim data As SqlDataAdapter = New SqlDataAdapter(Cmd)" com a seguinte ocorrência: Erro    1    Valor de tipo 'System.Data.SqlServerCe.SqlCeCommand' não pode ser convertido para 'System.Data.SqlClient.SqlCommand'.

    Realmente a minha tabela é do SQL SERVER COMPACT 4.0

    segunda-feira, 21 de março de 2016 17:16
  • Sobreira,

    É SqlCeServerDataAdapter.


    Antero Marques


    segunda-feira, 21 de março de 2016 18:05
  • Antero,

    Na linha "Dim cmd As SqlCeCommand = New SqlCeCommand("SELECT * FROM MISICAS where ([NOM_CANTOR] collate Latin1_General_CI_AI like  '%' + @valor + '%') or ([NOM_MUS] collate Latin1_General_CI_AI like '%' + @valor + '%')", _con)"
    qual a ação do @valor (é este mesmo o nome.

    Com a alteração proposta, na abertura do forme apresenta a mensagem "Não existe mapeamento de 'VarChar' para SqlDbType conhecido.


    segunda-feira, 21 de março de 2016 21:40
  • O @valor é o parâmetro de busca !

    Quanto ao erro...

    É porque SQL Server CE não suporta Varchar, tente o SqlDbType.NText

    Att,


    Antero Marques


    segunda-feira, 21 de março de 2016 22:17
  • Antero,

    Após várias tentativas e um número muito grande de pesquisas na internet, sem sucesso, estou na dúvida se é possível este procedimento para a tabela do SQL SERVER COMPACT 4.0.

    Continuarei estudando e pesquisando para saber se é possível este desenvolvimento.

    Grato,

    Sobreira

    terça-feira, 22 de março de 2016 15:34
  • Private Sub CarregaGrid(pesquisa As String)
    	Dim Constr As String = "Data Source=|DataDirectory|\Bd_CADASTRO.sdf"
            Dim _con As SqlCeConnection = New SqlCeConnection(Constr)
            Try
                _con.Open()
                Dim cmd As SqlCeCommand = New SqlCeCommand("SELECT * FROM MISICAS where ([NOM_CANTOR] collate Latin1_General_CI_AI like  '%' + @valor + '%') or ([NOM_MUS] collate Latin1_General_CI_AI like '%' + @valor + '%')", _con)
                cmd.Parameters.Add("valor", SqlDbType.NText, 80).Value = Pesquisa
                Dim data As SqlCeDataAdapter = New SqlCeDataAdapter(cmd)
                Dim dbset As DataSet = New DataSet()
                data.Fill(dbset, "MISICAS")
                Dim c = dbset.Tables("MISICAS").Rows.Count
                If (c > 0) Then
                    DataGridView1.DataSource = dbset
                    DataGridView1.DataMember = "MISICAS"
                    DataGridView1.Refresh()
                End If
    
            Catch ex As Exception
                MessageBox.Show(ex.Message)
                MessageBox.Show("Stack Trace: " & vbCrLf & ex.StackTrace)
            Finally
                _con.Close()
            End Try
        End Sub
    
    Private Sub Pesquisa_TextChanged(sender As Object, e As EventArgs) Handles Pesquisa.TextChanged
            CarregaGrid(Pesquisa.Text)
    End Sub

    Você tentou assim com NText e não foi também ?

    Seria bom alguém com o ambiente Compact para testar também.


    Antero Marques

    terça-feira, 22 de março de 2016 15:37
  • Foi tentado de todas as maneiras orientada, inclusive com Ntext.
    terça-feira, 22 de março de 2016 16:29
  • Após várias horas de pesquisa, achei no site da microsoft as seguintes orientações:

    CaseSensitivity

    Especifica a diferenciação de maiúsculas e minúsculas. O SQL Server Compact suporta somente a opção CI (não diferencia maiúsculas de minúsculas) através da cláusula COLLATE.

    AccentSensitivity

    Especifica que diferencia acentos (AS). O SQL Server Compact dá suporte apenas a essa opção.

    PELO QUE VI, ACHO QUE NÃO É POSSÍVEL EFETUAR A PESQUISA SEM/COM ACENTO. IREI PESQUISAR DE QUAL MANEIRO DEVO PROCEDER PARA CONTINUAR OPERANDO COM SQL SERVER COMPACT 4.0.

    quarta-feira, 23 de março de 2016 15:38