Alessandri gracias por tu interés en mi trabajo. Unas puntualizaciones:
Cita:1-Permitir copiar desde una hoja de cálculo y pegar en el grid.
El problema ahí es lo que llamas "copiar y pegar". Las hojas de cálculo tienen todas una opción de "guardar como csv", que creo que es lo correcto. y luego pasas ese csv como fuente de datos del Gridview, como digo en el ejemplo de la segunda mitad del vídeo.
Cita:Código:
....
...
Dim tm As String
Dim l As Single
Dim z As String
Dim final As String
Dim d As String
Dim tupla As New String[17]
Dim i As Integer
TituloGrid
tm = Len(ta.Text)
For l = 1 To tm
z = Mid(ta.Text, l, 1)
If z = "\t" Then
tupla[i] = d
i += 1
d = ""
Else
If z = "\n" Then
tabla2[Fl2, 0].Text = tupla[0]
tabla2[Fl2, 1].Text = tupla[1]
tabla2[Fl2, 2].Text = tupla[2]
tabla2[Fl2, 3].Text = tupla[3]
tabla2[Fl2, 4].Text = tupla[4]
tabla2[Fl2, 5].Text = tupla[5]
tabla2[Fl2, 6].Text = tupla[6]
tabla2[Fl2, 7].Text = tupla[7]
tabla2[Fl2, 8].Text = tupla[8]
tabla2[Fl2, 9].Text = tupla[9]
tabla2[Fl2, 10].Text = tupla[10]
...
...
En este procedimiento estás "destripando" un CSV que utiliza el tabulado como separador. En el control se asume que el separador es un ;. como puedes ver en éste código sacado de la clase extgrid del proyecto adjunto al vídeo (te subrayo en verde la línea donde se asume)
Cita:Private Sub Source_Write(Value As Variant)
Dim n As Integer
Dim asLine As String[]
Dim sValue As String
Dim v As Variant
Dim col As Collection
Me.Clear()
Try sValue = Value 'Intentamos meter el Value en un string
If Not Error Then
If Exist(Value) Then ' es un Path
asLine = Split(File.Load(Value), "\n", "", True)
Else
asLine = Split(Value, "\n", "", True) 'es el contenido del csv o un texto
Endif
$avSource = New Variant[]
For n = 0 To asLine.Max
$avSource.Add(Split(asLine[n], ";")) 'Asumimos el ; como separador. Se podría crear una propiedad, usar un inputbox o un formulario de opciones para afinar esto
Next
$asFieldNames = $avSource[0].Copy() 'usamos la primera línea como nombre de campo
$avSource.Extract(0) 'y la eliminamos del source
For n = 0 To $avSource[0].Max
$anFieldTypes.Add(CellType($avSource[0][n])) 'Determinamos el tipo de dato de cada celda según el contenido de la primera fila
Next
Else If Value Is String[] Then 'Es un String[] y lo convertimos en un Variant[][]
$avSource = New Variant[]
....
....
Como ves, el control que paso a los vídeos es una simplificación para no liarla mucho. Sin cambiarle nada, puedes, hacer algo como:
Código:
micsv = File.load(mipath&/nombreficherocsv)
micsv=replace(micsv,"\t",";")
file.save(mipath&/nombreficherocsv,micsv)
miExtGrid.Source=micsv
Esto si el carácter ";" no va a ocasionar conflicto con el contenido del fichero, claro. Si así fuese habría que cambiar el carácter en el código o añadir una propiedad "separator" al control para poder cambiarlo sin problemas.
Pero es mucho más sencillo, si eres tú quien genera el CSV decirle a la hoja de cálculo que utilice ";" como separador.
Cita:Código:
Private Sub TituloGrid()
tabla2.Clear
Fl2 = 0
tabla2.Columns.Count = 17 'Cantidad de Columnas de la tabla
tabla2.Rows.Count = 10000 'Cantidad del Filas
tabla2.columns.Resizable = True
tabla2.Columns[0].Text = "Nombre"
tabla2.Columns[0].Width = 110
tabla2.Columns[1].Text = "Apellidos"
tabla2.Columns[1].Width = 110
tabla2.Columns[2].Text = "Cédula"
tabla2.Columns[2].Width = 90
tabla2.Columns[3].Text = "Código"
tabla2.Columns[3].Width = 65
tabla2.Columns[4].Text = "Cargo"
tabla2.Columns[4].Width = 70
tabla2.Columns[5].Text = "Banco"
tabla2.Columns[5].Width = 70
tabla2.Columns[6].Text = "Cuenta"
tabla2.Columns[6].Width = 85
tabla2.Columns[7].Text = "Suel.Fijo"
tabla2.Columns[7].Width = 65
tabla2.Columns[8].Text = "Suel.Hora"
tabla2.Columns[8].Width = 65
tabla2.Columns[9].Text = "Sexo"
tabla2.Columns[9].Width = 40
tabla2.Columns[10].Text = "Comunidad"
tabla2.Columns[10].Width = 50
tabla2.Columns[11].Text = "Academico"
tabla2.Columns[11].Width = 50
tabla2.Columns[12].Text = "Clasific."
tabla2.Columns[12].Width = 50
tabla2.Columns[13].Text = "telefono1 y 2"
tabla2.Columns[13].Width = 50
tabla2.Columns[14].Text = "fecha"
tabla2.Columns[14].Width = 50
tabla2.Columns[15].Text = "contrato"
tabla2.Columns[15].Width = 50
tabla2.Columns[16].Text = "pad"
tabla2.Columns[16].Width = 1
End
Si cuando generas el csv en la hoja de cálculo le dices que utilice las cabeceras como primera línea te ahorrarás todo esto. Si tu hoja de cálculo no tiene las cabeceras adecuadas y quieres cambiarlas no es necesario este código. Para eso está la propiedad Titles del gridview. y los anchos de columna, si no te valen con ancho automático sólo tienes que introducirlos en la propiedad Widths. Con lo que se quedaría así:
Cita:Código:
micsv = File.load(mipath&/nombreficherocsv)
micsv=replace(micsv,"\t",";")
file.save(mipath&/nombreficherocsv,micsv)
miExtgrid.Source=micsv
miExtgrid.Titles=["Nombre","Apellidos","Cédula","Código","Cargo","Banco","Cuenta",...etc, etc.]
miExtgrid.Widths=[110,110,90,65,70,70,85...etc.etc]
De todas formas la generación de CSV no es tarea del control. El sólo los carga no los procesa. Eso queda para la Hoja de Cálculo... o para el programa del vídeo, donde puedes añadir todas las opciones y tejemanejes que quieras.
Un saludo.
(24-07-2021, 20:00)jguardon escribió: Hola, Shordi
Dos cuestiones:
Primera, veo que en el último campo de cada registro se crea un separador ; aún no siendo necesario porque ya tienes el salto de línea al siguiente registro. Esto podría provocar que se creen campos vacíos al final de cada registro dependiendo del programa que importe el fichero. Totalmente cierto. Se me pasó el detalle. Lo corrijo y actualizo el control adjunto al vídeo.
Segunda, si utilizamos el evento Data para cargar datos en el grid, podría ocurrir que sólo se exportasen los datos visibles en éste, ya que el evento sólo carga datos cuando deben visualizarse y no antes. Lo digo porque si la base de la creación del CSV es la iteración por las celdas del grid, no parece una buena idea.
Normalmente uno exporta y convierte los datos provenientes de la consulta, ya sea SQL o de otro tipo de fuente de datos, que es más fiable (y posiblemente más rápido) que "leer" las celdas una por una.
No se miran las celdas. los valores se extraen a través de la propiedad Value del array Source del control. Eso hace que sea más rápido que recurrir a la base de datos (al menos si la base de datos no es local de la máquina). La fiabilidad del tipo de datos devuelto (de caracter o numérico) es 100% si se cargó desde una base de datos y, digamos, al 90 por cien si se hizo desde un CSV. El código es éste tomado de la función Values_read() del control:
Código:
col = New Collection
For i = 0 To Me.Columns.Count - 1
Select Case $anFieldtypes[i]
Case gb.String
v = $avSource[anSelection[n]][i] 'donde $avSource es el array bidimensional fuente del Control.
Case gb.Integer
v = Val($avSource[anSelection[n]][i])
Case gb.Float
v = Val($avSource[anSelection[n]][i])
End Select
col.Add(v, $asFieldNames[i])
Next
En cualquier caso, puede ser de mucha utilidad para determinadas tareas pequeñas, gracias por enseñarnos tu trabajo, shordi.
Saludos
y gracias por tu interés.
Saludos