El separador decimal, CurrentCulture y ado.net

11/06/2006 - 12:44 por Lilam | Informe spam
El separador decimal, CurrentCulture y ado.net

Necesito modificar el separador decimal del sistema debido a que es la única
forma que conozco para que funcionen ficheros CSV con la "," como
delimitador de campo y necesito utilizar este tipo de fichero como entrada
de una base de datos.
El problema es que he estado probando ciertas cosas con el
System.Globalization tales como

Thread.CurrentThread.CurrentCulture = New CultureInfo("en-US", False)

y al parecer ado.net y OleDb hacen caso omiso de la cultura que establezcas
para el Framework 2.0 y la aplicación.

En VB6 utilizaba la API de Win32 para establecer el CurrencyDecimalSeparator
y el NumberDecimalSeparator a "." del sistema mientras obtenía los datos de
los ficheros y posteriormente reestablecer a su valor original con el fin de
evitar el temido error...


'El separador de campos de la especificación de archivo de texto coincide
con el separador decimal o el delimitador de texto.'

Después de muchas horas de insomnio no he encontrado nada que me sirva de
ayuda y que no haya probado así que si alguien que tenga el "know how" del
asunto es tan amable de echarme una mano le estaré agradecido.

Preguntas similare

Leer las respuestas

#1 SoftJaén
11/06/2006 - 15:39 | Informe spam
"Lilam" escribió:

Necesito modificar el separador decimal del sistema debido a que es la
única forma que conozco para que funcionen ficheros CSV con la "," como
delimitador de campo y necesito utilizar este tipo de fichero como entrada
de una base de datos.

y al parecer ado.net y OleDb hacen caso omiso de la cultura que
establezcas para el Framework 2.0 y la aplicación.

'El separador de campos de la especificación de archivo de texto coincide
con el separador decimal o el delimitador de texto.'

Después de muchas horas de insomnio no he encontrado nada que me sirva



Hola:

No es que ADO .NET, el proveedor .net OleDb o el marco de trabajo 2.0 hagan
caso omiso de la cultura. El problema está en que existe un driver llamado
ISAM de texto, el cual nos lo proporciona el motor Microsoft Jet, y éste no
entiende de delimitadores de campo con comas, cuando el símbolo separador
decimal existente en la configuración regional coincide con la coma, como es
el caso de una configuración regional de español. Así que la única solución
que tienes (o al menos es la que yo conozco), pasa porque el archivo de
texto tenga otro símbolo para delimitar los campos, o bien, cambiar
temporalmente la configuración regional el tiempo suficiente que te lleve
abrir el archivo de texto y leer el contenido del mismo.

Y esto último es lo que te voy a explicar, aprovechando un código fuente que
tenía a mano, y que lo he adaptado un poco deprisa para ejecutarlo con
Visual Basic .NET ó 2005.

Inicia una nueva solución, añade un control DataGridView (o DataGrid, si
usas VB 2003) al formulario y pasa a la ventana de código, donde deberás
importar el siguiente espacio de nombres:

Imports System.Data.OleDb

Al comienzo de la clase «Form1», copia las siguientes declaraciones de las
funciones API, teniendo en cuenta que los tipos de datos cambian: donde
antes eran «Long» ahora son «Integer»:

Private Declare Function GetLocaleInfo _
Lib "kernel32" Alias "GetLocaleInfoA" ( _
ByVal locale As Integer, _
ByVal lCType As Integer, _
ByVal lpLCData As String, _
ByVal cchData As Integer) As Integer

Private Declare Function SetLocaleInfo _
Lib "kernel32" Alias "SetLocaleInfoA" ( _
ByVal locale As Integer, _
ByVal lCType As Integer, _
ByVal lpLCData As String) As Integer

Por último, en el evento «Load» del formulario copia/pega el siguiente
código:

Dim sepDecimal1, sepDecimal2, buffer As String
Const LOCALE_USER_DEFAULT As Integer = &H400
Dim cnn As New OleDbConnection

' Guardamos el valor del Separador decimal
'
buffer = New String(CChar(" "), 100)
GetLocaleInfo(LOCALE_USER_DEFAULT, &HE, Buffer, 99)
sepDecimal1 = Strings.Left(Buffer, InStr(Buffer, Chr(0)) - 1)

' Establecemos el nuevo separador decimal
'
SetLocaleInfo(LOCALE_USER_DEFAULT, &HE, ".")

' Guardamos el valor del Separador decimal monetario
'
Buffer = New String(CChar(" "), 100)
GetLocaleInfo(LOCALE_USER_DEFAULT, &H16, Buffer, 99)
sepDecimal2 = Strings.Left(Buffer, InStr(Buffer, Chr(0)) - 1)

' Establecemos el nuevo separador decimal monetario
'
SetLocaleInfo(LOCALE_USER_DEFAULT, &H16, ".")

Try
' Configuramos y abrimos la conexión
With cnn
.ConnectionString = _
"Provider = Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\Mis documentos;" & _
"Extended Properties='TEXT;HDR=Yes;'"
.Open()
End With

Dim da As New OleDbDataAdapter
Dim ds As New DataSet

' Creamos un objeto Command para seleccionar
' el archivo de texto que deseamos abrir.
'
Dim oCommand As New _
OleDbCommand("Select * From Archivo#csv", cnn)

' Asignamos el comando a la propiedad SelectCommand
' del objeto DataAdapter.
'
da.SelectCommand = oCommand

' Rellenamos la tabla con el conjunto de datos
'
da.Fill(ds, "ArchivoDeTexto")

' Configuramos el DataGridView
'
DataGridView1.DataSource = ds.Tables("ArchivoDeTexto")

Catch ex As OleDbException
MessageBox.Show(ex.Errors(0).Message, _
"Abrir archivo de texto", _
MessageBoxButtons.OK, _
MessageBoxIcon.Exclamation)

Catch ex As Exception
MessageBox.Show(ex.Message, _
"Abrir archivo de texto", _
MessageBoxButtons.OK, _
MessageBoxIcon.Exclamation)

Finally
' Cerramos la conexión
cnn.Close()
cnn = Nothing

' Restablecemos el separador decimal
SetLocaleInfo(LOCALE_USER_DEFAULT, &HE, sepDecimal1)

' Restablecemos el separador decimal monetario
SetLocaleInfo(LOCALE_USER_DEFAULT, &H16, sepDecimal2)

End Try

Por último, ni que decir tiene que deberás de hacer uso de un archivo de
configuración de esquema llamado «Schema.ini», el cual debe residir en la
misma carpeta donde se encuentre el archivo de texto que deseas abrir.

Si deseas más información sobre cómo trabajar con archivos de texto,
consulta el artículo técnico que te indico más abajo, que aunque los
ejemplos están escritos en Visual Basic 6.0, son fácilmente adaptables a
Visual Basic .NET, aparte que la teoría es la misma.

Trabajar con los datos de un archivo de texto
http://mvp-access.com/softjaen/arti...t_isam.htm

Un saludo

Enrique Martínez
[MS MVP - VB]

Nota informativa: La información contenida en este mensaje, así como el
código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin
garantías de ninguna clase, y no otorga derecho alguno. Usted asume
cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o
sugerido en el presente mensaje.
Respuesta Responder a este mensaje
#2 Lilam
11/06/2006 - 21:07 | Informe spam
Enrrique,
muchas gracias por tu tiempo y respuesta, la verdad es que soy nuevo por
aquí y no me esperaba
una respuesta tan inmediata lo mismo que profesional.

Comentarte que no entiendo mucho de arquitectura pero ya conocia el tema del
ISAM y el «Schema.ini»,
de hecho el mismo proyecto lo tengo en VB6 de manera muy similar a como me
has comentado posiblemente de algun articulo tuyo anterior
lo que no era consciente que lo podia iplementar de manera similar en VB2005
crei que con el tema de las cultures
podria solucionarlo sin tener que tocar la configuración regional.

Un saludo y
muchas gracias de nuevo.

Lilam

From: "SoftJaén"
Newsgroups: microsoft.public.es.dotnet.vb
Sent: Sunday, June 11, 2006 3:39 PM
Subject: Re: El separador decimal, CurrentCulture y ado.net


"Lilam" escribió:

Necesito modificar el separador decimal del sistema debido a que es la
única forma que conozco para que funcionen ficheros CSV con la "," como
delimitador de campo y necesito utilizar este tipo de fichero como
entrada
de una base de datos.

y al parecer ado.net y OleDb hacen caso omiso de la cultura que
establezcas para el Framework 2.0 y la aplicación.

'El separador de campos de la especificación de archivo de texto coincide
con el separador decimal o el delimitador de texto.'

Después de muchas horas de insomnio no he encontrado nada que me sirva



Hola:

No es que ADO .NET, el proveedor .net OleDb o el marco de trabajo 2.0
hagan
caso omiso de la cultura. El problema está en que existe un driver llamado
ISAM de texto, el cual nos lo proporciona el motor Microsoft Jet, y éste
no
entiende de delimitadores de campo con comas, cuando el símbolo separador
decimal existente en la configuración regional coincide con la coma, como
es
el caso de una configuración regional de español. Así que la única
solución
que tienes (o al menos es la que yo conozco), pasa porque el archivo de
texto tenga otro símbolo para delimitar los campos, o bien, cambiar
temporalmente la configuración regional el tiempo suficiente que te lleve
abrir el archivo de texto y leer el contenido del mismo.

Y esto último es lo que te voy a explicar, aprovechando un código fuente
que
tenía a mano, y que lo he adaptado un poco deprisa para ejecutarlo con
Visual Basic .NET ó 2005.

Inicia una nueva solución, añade un control DataGridView (o DataGrid, si
usas VB 2003) al formulario y pasa a la ventana de código, donde deberás
importar el siguiente espacio de nombres:

Imports System.Data.OleDb

Al comienzo de la clase «Form1», copia las siguientes declaraciones de las
funciones API, teniendo en cuenta que los tipos de datos cambian: donde
antes eran «Long» ahora son «Integer»:

Private Declare Function GetLocaleInfo _
Lib "kernel32" Alias "GetLocaleInfoA" ( _
ByVal locale As Integer, _
ByVal lCType As Integer, _
ByVal lpLCData As String, _
ByVal cchData As Integer) As Integer

Private Declare Function SetLocaleInfo _
Lib "kernel32" Alias "SetLocaleInfoA" ( _
ByVal locale As Integer, _
ByVal lCType As Integer, _
ByVal lpLCData As String) As Integer

Por último, en el evento «Load» del formulario copia/pega el siguiente
código:

Dim sepDecimal1, sepDecimal2, buffer As String
Const LOCALE_USER_DEFAULT As Integer = &H400
Dim cnn As New OleDbConnection

' Guardamos el valor del Separador decimal
'
buffer = New String(CChar(" "), 100)
GetLocaleInfo(LOCALE_USER_DEFAULT, &HE, Buffer, 99)
sepDecimal1 = Strings.Left(Buffer, InStr(Buffer, Chr(0)) - 1)

' Establecemos el nuevo separador decimal
'
SetLocaleInfo(LOCALE_USER_DEFAULT, &HE, ".")

' Guardamos el valor del Separador decimal monetario
'
Buffer = New String(CChar(" "), 100)
GetLocaleInfo(LOCALE_USER_DEFAULT, &H16, Buffer, 99)
sepDecimal2 = Strings.Left(Buffer, InStr(Buffer, Chr(0)) - 1)

' Establecemos el nuevo separador decimal monetario
'
SetLocaleInfo(LOCALE_USER_DEFAULT, &H16, ".")

Try
' Configuramos y abrimos la conexión
With cnn
.ConnectionString = _
"Provider = Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\Mis documentos;" & _
"Extended Properties='TEXT;HDR=Yes;'"
.Open()
End With

Dim da As New OleDbDataAdapter
Dim ds As New DataSet

' Creamos un objeto Command para seleccionar
' el archivo de texto que deseamos abrir.
'
Dim oCommand As New _
OleDbCommand("Select * From Archivo#csv", cnn)

' Asignamos el comando a la propiedad SelectCommand
' del objeto DataAdapter.
'
da.SelectCommand = oCommand

' Rellenamos la tabla con el conjunto de datos
'
da.Fill(ds, "ArchivoDeTexto")

' Configuramos el DataGridView
'
DataGridView1.DataSource = ds.Tables("ArchivoDeTexto")

Catch ex As OleDbException
MessageBox.Show(ex.Errors(0).Message, _
"Abrir archivo de texto", _
MessageBoxButtons.OK, _
MessageBoxIcon.Exclamation)

Catch ex As Exception
MessageBox.Show(ex.Message, _
"Abrir archivo de texto", _
MessageBoxButtons.OK, _
MessageBoxIcon.Exclamation)

Finally
' Cerramos la conexión
cnn.Close()
cnn = Nothing

' Restablecemos el separador decimal
SetLocaleInfo(LOCALE_USER_DEFAULT, &HE, sepDecimal1)

' Restablecemos el separador decimal monetario
SetLocaleInfo(LOCALE_USER_DEFAULT, &H16, sepDecimal2)

End Try

Por último, ni que decir tiene que deberás de hacer uso de un archivo de
configuración de esquema llamado «Schema.ini», el cual debe residir en la
misma carpeta donde se encuentre el archivo de texto que deseas abrir.

Si deseas más información sobre cómo trabajar con archivos de texto,
consulta el artículo técnico que te indico más abajo, que aunque los
ejemplos están escritos en Visual Basic 6.0, son fácilmente adaptables a
Visual Basic .NET, aparte que la teoría es la misma.

Trabajar con los datos de un archivo de texto
http://mvp-access.com/softjaen/arti...t_isam.htm

Un saludo

Enrique Martínez
[MS MVP - VB]

Nota informativa: La información contenida en este mensaje, así como el
código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin
garantías de ninguna clase, y no otorga derecho alguno. Usted asume
cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado
o
sugerido en el presente mensaje.






email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida