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

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.
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#)
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
-
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!
-
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
-
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
-
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
- Editado Antero Marques sábado, 19 de março de 2016 05:20
-
-
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
- Editado Antero Marques sábado, 19 de março de 2016 17:12
-
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 SubPORÉ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"
-
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.
-
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'.
-
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'.
-
-
-
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
- Editado 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
-
Sobreira,
É SqlCeServerDataAdapter.
Antero Marques
- Editado Antero Marques segunda-feira, 21 de março de 2016 19: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.
-
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
- Editado Antero Marques segunda-feira, 21 de março de 2016 22:19
-
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
-
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
-
-
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.