Excel y C#

04/12/2008 - 13:51 por Francisco Matamoros | Informe spam
Hola a todos, estoy intentado rellenar una hoja de excel que el usuario
elige y donde escribe "variables" del tipo
[A1], [B7] y que yo en mi programa tengo perfectamente definidas y sé sus
valores.
Cuando abro con ADO Excel, el select no sé como hacerlo pues no sé como se
llama la hoja del libro que elija el usuario puesto que es el usuario el que
las diseña a su gusto.
Tendría que saber cómo se llaman las hojas que componen el xls, y en un
combo que me eligiera cuál quiere rellenar, o si quiere rellenar varias, el
caso es que en cualquier caso no sé como se llaman las hojas y las necesito
para el select.
Una vez que pudiera resolver lo anterior, y haciendo pruebas con un select
"a piñón" del estilo "Select * from [Hoja1$]" me trata el título del
informe, p.e. BALANCE DE SUMAS Y SALDOS, como nombre de columna y no me
interesa eso.
En definitiva lo he hecho en Excel porque se diseña mejor por el usuario,
puede poner tantas filas y columnas como quiera y únicamente rellenar con
"variables" del tipo que he escrito antes los datos que yo le relleno desde
el programa, pero no encuentro una salida a esto.
Si pudiera leer todo el contenido de la excel utilizando sus filas y
columnas y pudiendo hacer referencias a ellas para ir buscando texto del
tipo [XX] y yo poder cambiarlo estaría muy satisfecho.
A ver si alguien ha hecho algo parecido y me puede orientar.
Perdón por el ladrillazo y saludos.

Preguntas similare

Leer las respuestas

#1 SoftJaén
04/12/2008 - 16:02 | Informe spam
"Francisco Matamoros" escribió:

Tendría que saber cómo se llaman las hojas que componen el xls, y en un
combo que me eligiera cuál quiere rellenar, ...



Hola, Francisco:

El método «GetSchema» de un objeto OleDbConnection, te devuelve un objeto
DataTable con la información de esquema del origen de datos especificado.

Traduce a C# el código de la siguiente función escrita en Visual Basic .net:

Private Function GetRangesAndSheetsNames( _
ByVal connString As String, _
ByVal includeSheets As Boolean, _
ByVal includeRanges As Boolean) As String()

If (connString = String.Empty) Then Return Nothing

Dim cnn As OleDbConnection = Nothing

Try
cnn = New OleDbConnection(connString)
cnn.Open()

Dim dt As DataTable = cnn.GetSchema("TABLES")

Dim tables() As String = Nothing
Dim o As Object = Nothing
Dim n As Int32 = 0

If dt.Rows.Count > 0 Then

For Each dr As DataRow In dt.Rows

o = dr.Item("TABLE_TYPE")

If (o.ToString.ToUpper = "TABLE") Then
' El objeto es una tabla.
'
o = dr.Item("TABLE_NAME")

' Si el nombre contiene el carácter $, se
' trata del nombre de una hoja; en caso
' contrario, se trata del nombre de un rango.
'
' NOTA: Si el nombre de la hoja de cálculo contiene
' espacios en blanco (Mi Nombre Hoja), el nombre
' estará encerrado entre comillas simples
' ('Mi Nombre Hoja$')
'
Dim p As Int32 = o.ToString.IndexOf("$"c)

' Si se trata de un rango con nombre, y éstos
' no se incluyen, continuamos.
'
If p = -1 AndAlso Not includeRanges Then _
Continue For

' Si se trata de una hoja de cálculo, y éstas
' no se incluyen, continuamos.
'
If p <> -1 AndAlso Not includeSheets Then _
Continue For

ReDim Preserve tables(n)
tables(n) = o.ToString
n += 1
End If

Next dr

End If

Return tables

Catch ex As Exception

Return Nothing

Finally
' Cerramos la conexión si procede.
'
If cnn.State <> ConnectionState.Closed Then cnn.Close()
cnn = Nothing

End Try

End Function

Ahora, a la función simplemente la llamarías de la siguiente manera:

' Construimos la cadena de conexión.
'
Dim connString As String = _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\Mis documentos\Libro1.xls;" & _
"Extended Properties='Excel 8.0;HDR=Yes'"

' Indicamos que deseamos recuperar tanto el nombre de
' las hojas de cálculo como el de los rangos de celdas
' con nombre.
'
Dim ranges() As String = _
GetRangesAndSheetsNames(connString, True, True)

ComboBox1.Items.Clear()

' Añadimos los elementos al control ComboBox.
'
For Each range As String In ranges
ComboBox1.Items.Add(range)
Next

ComboBox1.SelectedIndex = 0

¡Eso es todo! Adapta el ejemplo a tus necesidades.

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 Francisco Matamoros
04/12/2008 - 16:16 | Informe spam
Gracias Enrique, completo y válido para lo que necesito.
Ahora me faltaría cambiar valores en celdas y guardar la hoja de Excel con
los valores cambiados.

"SoftJaén" escribió en el mensaje
news:
"Francisco Matamoros" escribió:

Tendría que saber cómo se llaman las hojas que componen el xls, y en un
combo que me eligiera cuál quiere rellenar, ...



Hola, Francisco:

El método «GetSchema» de un objeto OleDbConnection, te devuelve un objeto
DataTable con la información de esquema del origen de datos especificado.

Traduce a C# el código de la siguiente función escrita en Visual Basic
.net:

Private Function GetRangesAndSheetsNames( _
ByVal connString As String, _
ByVal includeSheets As Boolean, _
ByVal includeRanges As Boolean) As String()

If (connString = String.Empty) Then Return Nothing

Dim cnn As OleDbConnection = Nothing

Try
cnn = New OleDbConnection(connString)
cnn.Open()

Dim dt As DataTable = cnn.GetSchema("TABLES")

Dim tables() As String = Nothing
Dim o As Object = Nothing
Dim n As Int32 = 0

If dt.Rows.Count > 0 Then

For Each dr As DataRow In dt.Rows

o = dr.Item("TABLE_TYPE")

If (o.ToString.ToUpper = "TABLE") Then
' El objeto es una tabla.
'
o = dr.Item("TABLE_NAME")

' Si el nombre contiene el carácter $, se
' trata del nombre de una hoja; en caso
' contrario, se trata del nombre de un rango.
'
' NOTA: Si el nombre de la hoja de cálculo contiene
' espacios en blanco (Mi Nombre Hoja), el nombre
' estará encerrado entre comillas simples
' ('Mi Nombre Hoja$')
'
Dim p As Int32 = o.ToString.IndexOf("$"c)

' Si se trata de un rango con nombre, y éstos
' no se incluyen, continuamos.
'
If p = -1 AndAlso Not includeRanges Then _
Continue For

' Si se trata de una hoja de cálculo, y éstas
' no se incluyen, continuamos.
'
If p <> -1 AndAlso Not includeSheets Then _
Continue For

ReDim Preserve tables(n)
tables(n) = o.ToString
n += 1
End If

Next dr

End If

Return tables

Catch ex As Exception

Return Nothing

Finally
' Cerramos la conexión si procede.
'
If cnn.State <> ConnectionState.Closed Then cnn.Close()
cnn = Nothing

End Try

End Function

Ahora, a la función simplemente la llamarías de la siguiente manera:

' Construimos la cadena de conexión.
'
Dim connString As String = _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=C:\Mis documentos\Libro1.xls;" & _
"Extended Properties='Excel 8.0;HDR=Yes'"

' Indicamos que deseamos recuperar tanto el nombre de
' las hojas de cálculo como el de los rangos de celdas
' con nombre.
'
Dim ranges() As String = _
GetRangesAndSheetsNames(connString, True, True)

ComboBox1.Items.Clear()

' Añadimos los elementos al control ComboBox.
'
For Each range As String In ranges
ComboBox1.Items.Add(range)
Next

ComboBox1.SelectedIndex = 0

¡Eso es todo! Adapta el ejemplo a tus necesidades.

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
#3 SoftJaén
04/12/2008 - 16:42 | Informe spam
"Francisco Matamoros" escribió:

Ahora me faltaría cambiar valores en celdas y guardar la hoja
de Excel con los valores cambiados.



Si vas a trabajar con el ISAM de Excel del motor Microsoft Jet, no te va a
queda más remedio que ejecutar las correspondientes consultas SQL de
actualización para modificar los datos de las celdas.

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
#4 SoftJaén
04/12/2008 - 16:59 | Informe spam
"Francisco Matamoros" escribió:

Perdona Enrique, traduciendo a c# escribo:

DataTable dt = objConn (aquí no tengo ningún GetSchema)

y no puedo continar.



Digo yo que tendrás que llamar expresamente al método «GetSchema» del objeto
OleDbConnection, pasándole como argumento el nombre «TABLES».

Aquí tienes traducido el código que has expuesto:

string sConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=C:\\Mis documentos\\Libro1.xls;" +
"Extended Properties='Excel 8.0;HDR=Yes'";

OleDbConnection objConn = new OleDbConnection(sConnectionString);

objConn.Open();

DataTable dt = objConn.GetSchema("TABLES");

Me imagino que las variables «Entorno.RutaInformes + libroExcel» devolverá
una ruta válida a un archivo de Excel.

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
#5 SoftJaén
04/12/2008 - 17:21 | Informe spam
"Francisco Matamoros" escribió:

No sé si depende de la versión 2003 que es la que yo utilizo, pero
no me deja ni compilar esta línea:

DataTable dt = objConn.GetSchema("TABLES");

c:\visual\galcon\libroscontables\formemisionmanual.cs(231,19):
error CS0117: 'System.Data.OleDb.OleDbConnection'
no contiene una definición para 'GetSchema'



Claro que depende de la versión. El método «GetSchema» se introdujo en la
versión 2.0 del marco de trabajo de .net, es decir, con Visual Studio 2005.

Pues si estás utilizando Visual Studio 2003, ignoro en estos momentos cómo
puedes recuperar la información de esquema del libro de trabajo de Excel.

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
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida