elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Únete al Grupo Steam elhacker.NET


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP)
| | | |-+  Programación Visual Basic (Moderadores: LeandroA, seba123neo)
| | | | |-+  Guardar list2 y leer list1
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: 1 2 3 4 5 [6] Ir Abajo Respuesta Imprimir
Autor Tema: Guardar list2 y leer list1  (Leído 16,181 veces)
Serapis
Colaborador
***
Desconectado Desconectado

Mensajes: 3.357


Ver Perfil
Re: Guardar list2 y leer list1
« Respuesta #50 en: 1 Mayo 2022, 17:03 pm »

El proyecto ha sido cambiado en profundidad en más de una vez... si de último te dí el proyecto completo y funcional, porqué ahora el código en tus funciones no vene a coincidir con el código que te pasé la última vez....?

Veamos, si tratas de crear una nueva facturación... se deben crear dos ficheros un fichero *.data y un fichero *.regdata (resultado de las últimas modificaciones), el caso es que siendo 'nueva' el número de registros será 0... porque se acaba de crear la facturación, el contenido de dichos ficheros será 0 registros...

Así que al invocar 'leer facturación' solo se ejecurtará esa parte del código si se da esta condición:
Código
  1. If (NumRegistros > 0) Then
Así que al crear la facturación no deberia acceder a esa zona... y por qué accede a esa zona si debiera haber 0 registros?. Porque o bien usas la versión vieja del código o bien lo has modificado eliminando código.... hasta probar que los cambios funcionan bien, mejor que eliminar es comentar código, si el cambio es bastante grande que no solo se borren alguna slíneas y tal, entonces es preferible copiar la función y dejarla comentada al completo, y por tanto hacer cambios sobre una copia... así, si algo falla (que antes funcionaba, esto es mismo código) puede verificarse la diferencia entre ambos códigos para reconocer que está sucediendo.

Tu tienes esté código:
Código
  1. Private Function CrearNuevaFacturacion(ByRef NombreFile As String) As Boolean
  2. Dim Ruta As String
  3.  
  4.    If (Abierto = True) Then Call Cerrar(Canal)
  5.  
  6.    Ruta = (App.Path & "\" & NombreFile)
  7.    If (Abrir(Ruta, Canal, True) = True) Then
  8.        Call UpdateHeader(0, 0)
  9.        CrearNuevaFacturacion = True
  10.    Else
  11.        MsgBox "Parece que el fichero que intenta abrir ya existe, elija otro nombre (o bien ocurrio un error)..."
  12.    End If
  13. End Function
Y para la misma función al final cambió a este:

Código
  1. ' La creacion de una NUEVA facturacion supone crear ambos ficheros:
  2. '   1 - "Facturacion xxx.reg"
  3. '   2 - "Facturacion xxx.regdata"
  4. Private Function CrearNuevaFacturacion(ByRef NombreFileLote As String, ByRef NombreFileProd As String, ByVal NFacturaInicial As Integer) As Boolean
  5.    Dim Ruta As String
  6.  
  7.    Call CerrarFacturacion
  8.  
  9.    Ruta = (App.Path & "\" & NombreFileLote)
  10.    If (Abrir(Ruta, CanalLote, True) = True) Then
  11.        Ruta = (App.Path & "\" & NombreFileProd)
  12.        If (Abrir(Ruta, CanalProducto, True) = True) Then
  13.            Get #CanalLote, 1, NumRegsLotes
  14.            Get #CanalLote, , AutoIncLote
  15.  
  16.            ' Usar el parámetro 'NFacturaInicial' (para que funcione correctamente), implica más cambios en el código que no se efectuaron, pues surgió como una sugerencia de una interpretación errónea de cierta petición que hiciste.
  17.            'If (NFacturaInicial > 1) Then
  18.            '    AutoIncLote = (NFacturaInicial - 1) ' cuando se compre se incrementa en 1
  19.                AutoIncLote = 0
  20.                Put #CanalLote, 3, AutoIncLote
  21.            'End If
  22.  
  23.            Get #CanalProducto, 1, NumRegsProds
  24.            Get #CanalProducto, , AutoIncProducto
  25.  
  26.            mnuLotes(0).Enabled = True
  27.            CrearNuevaFacturacion = True
  28.            Exit Function
  29.        End If
  30.    End If
  31.  
  32.    If (Err.Number = 0) Then
  33.        Call MsgBox("Parece que uno o ambos ficheros asociados a la facturacion que intenta abrir ya existe, elija otro nombre (o bien ocurrió un error)...", vbExclamation, "Crear Nueva Facturacion: Ya existe...")
  34.    Else
  35.        Err.Clear
  36.        Call MsgBox("Ocurrio un error inesperado al tratar de abrir la facturacion seleccionada..." & vbCrLf & Err.Description, vbExclamation, "Crear Nueva Facturacion: Error inesperado...")
  37.    End If
  38. End Function
  39.  

Como se ve, recibe dos parámetros para los ficheros, no solo uno, y observo que en tu código falta la llamada a la función 'CerrarFacturacion' que es la que pondrá a 0 todas las variables globales referidas a una facturación como es 'NumRegistros'. La función debe invocarse tanto si había abierta previamente una facturación como si no... allí mismo se verifica si estaba abierta y se cierra.

Además, según veo allí (y que de memoria ya no recordaba), la variable NumRegistros, fue cambiada de nombre al separar en dos ficheros la comprar de los productos de cada compra:
Código
  1. ' Cierra los dos ficheros asociados a la misma facturacion.
  2. Private Function CerrarFacturacion()
  3.    If (Abierto = True) Then
  4.        Call CerrarCarrito
  5.  
  6.        Close #CanalLote
  7.        Close #CanalProducto
  8.        Call ActivarInterfaz(False)  ' desactivar de la interfaz, lo que proceda...
  9.    End If
  10.  
  11.    mnuLotes(0).Enabled = False
  12.    CanalLote = 0: NumRegsLotes = 0: AutoIncLote = 0
  13.    CanalProducto = 0: NumRegsProds = 0: AutoIncProducto = 0
  14.    TotalContado = 0: TotalCredito = 0
  15.    Call ShowTotales
  16. End Function
  17.  

NumRegsLotes y NumRegsProds (creo recordar), remplazan a NumRegistros.


El error que te arroja el código, se produce simplemente porque el tipo de datos del parámetro que se pasa no coincide con el tipo de datos que la función invocada espera... y es razonable porque al separar la factura en 2 ficheros uno que contiene los datos estrictos de la compra y otro el detalle de cada artículo comprado, exigió crear un registro específico para cada fichero, quedando el registro que antes se usaba para el único fichero obsoleto...
si se revisa la función que da el fallo:
Código
  1. Public Function RegCompraToString(ByRef Registro As RegLote, Optional ByRef Separador As String = CHAR_SEP) As String
  2.    Dim R As String, S As String, T As String
  3.  
  4.    With Registro
  5.        R = (FillSizeStr(CStr(.IdPedido), 5, True) & Separador & FillSizeStr(CStr(.Cantidad), 5, True))
  6.        S = (FillSizeStr(CStr(.Descuento), 7, True, 3) & Separador & FillSizeStr(CStr(.Total), 7, True, 3))
  7.        T = GetMetodoPago(.MetodoDePago) & Separador & CStr(.FechaCompra)
  8.  
  9.        RegCompraToString = (R & Separador & S & Separador & T)
  10.    End With
  11. End Function
  12.  
Reclama un parámetro del tipo 'RegLote' (ByRef Registro As RegLote). Dicha función fue modificada, para adaptarse a los cambios de la separación de la compra en sendos ficheros. No recuerdo si además cambié el nombre de la estructura (probablemente):
Código
  1. ' Ahora el registro de lote, va aparte de los registro de los articulos especificos comprados en el lote.
  2. Public Type RegLote                                         ' 32 bytes por registro
  3.    IdPedido                            As Integer          ' 01  Cada lote, comprado tiene su id unico que se aplica a todos los articulos comprados en ese lote.
  4.      Reservado1                        As Integer          ' 03     (Reservado: Por si se debe cambiar el Id a tipo long, sin alterar los ficheros).
  5.      Reservado2                        As Integer          ' 05     Para futurible ampliacion
  6.      Reservado3                        As Long             ' 07     Para futurible ampliacion
  7.    Descuento                           As Single           ' 11  Descuento (Solo se aplica, para las ofertas de tipo: 1,2 y 4, en otro caso el valor es siempre 0).
  8.    Total                               As Single           ' 15  Coste total del lote comprado.
  9.    FechaCompra                         As Date             ' 19  Fecha de compra del lote (fecha y hora)
  10.    MetodoDePago                        As Byte             ' 27  Metodo de pago
  11.    Cantidad                            As Byte             ' 29  Cantidad de productos comprados en el lote.
  12.    Index                               As Long             ' 29  Puntero a un fichero que contiene los idCompra de cada articulo comprado en el lote.
  13. End Type
  14.  
Como se ve, el registro solo contiene datos informativos del lote comprado, entre los que incluye los necesarios para rescatar los registros asociados con los detalles de los artículos comprados (campos: 'Cantidad' e 'Index'). Los comentarios, no se ponen por poner... detallan que son o porque están.


Tu tienes la función 'LeerFacturación', con el siguiente código:
Código
  1. Private Function LeerFacturacion(ByRef Ruta As String) As Boolean
  2.   Dim k As Integer
  3.  
  4.    If (Abierto = True) Then Call Cerrar(Canal)
  5.  
  6.    If (Abrir(Ruta, Canal) = True) Then
  7.        Get #Canal, 1, NumRegistros
  8.        Get #Canal, , AutoIncLote
  9.        Get #Canal, , AutoIncProducto
  10.  
  11.        If (NumRegistros > 0) Then
  12.            With List1
  13.                .Clear
  14.                For k = 1 To NumRegistros
  15.                    Get #Canal, , RegX
  16.                    Call .AddItem(RegCompraToString(RegX, CHAR_SEP))
  17.                Next
  18.  
  19.                ' Ahora si se quiere puede leerse de nuevo el primer registro para transferirlo a los textbox...
  20.                .ListIndex = 0 ' para ello delegamos en el codigo que pondremos al listbox...
  21.            End With
  22.        End If
  23.  
  24.        LeerFacturacion = True
  25.    End If
  26. End Function
  27.  

Revisando, en el último proyecto que te pasé.., ni siquiera tengo una función con ese nombre, la que se encarga de la lectura de una facturación se llama 'ListarFacturacion', y tiene este código:
Código
  1. ' Abre y carga el fichero de facturacion. Tambien abre el fichero de productos comprados (solo carga los productos asociados al primer lote en el listado).
  2. ' NOTA: No establecer la propiedad SORTED a TRUE, en los listados afectados.
  3. Private Function ListarFacturacion(ByRef Ruta1 As String, ByRef Ruta2 As String) As Boolean
  4.    Dim k As Integer
  5.  
  6.    Call CerrarFacturacion
  7.  
  8.    If ((Abrir(Ruta1, CanalLote) = True) And (Abrir(Ruta2, CanalProducto) = True)) Then
  9.        Get #CanalLote, 1, NumRegsLotes
  10.        Get #CanalLote, , AutoIncLote
  11.  
  12.        Get #CanalProducto, 1, NumRegsProds
  13.        Get #CanalProducto, , AutoIncProducto
  14.  
  15.        If (NumRegsLotes > 0) Then
  16.            With LisLotes
  17.                .Clear
  18.  
  19.                Call PosicionarRegLote(1)       ' alli se resta 1
  20.                For k = 0 To NumRegsLotes - 1
  21.                    Get #CanalLote, , RegX
  22.                    Call .AddItem(RegCompraToString(RegX))
  23.                    .ItemData(k) = RegX.IdPedido
  24.  
  25.                    If (RegX.MetodoDePago = MetodosDePago.PAGO_AL_CONTADO) Then
  26.                        TotalContado = (TotalContado + RegX.Total)
  27.                    Else
  28.                        TotalCredito = (TotalCredito + RegX.Total)
  29.                    End If
  30.                Next
  31.  
  32.                Call ShowTotales
  33.  
  34.                ' Ahora si se quiere puede leerse de nuevo el primer registro para transferirlo a los textbox...
  35.                .ListIndex = 0 ' para ello delegamos en el codigo que pondremos al listbox...
  36.            End With
  37.        End If
  38.  
  39.        mnuLotes(0).Enabled = True
  40.        ListarFacturacion = True
  41.    End If
  42. End Function
  43.  
Como se puede ver, se abren 2 ficheros, el *.data y el *.regdata, e igualmente se lee de ambos, su cabecera y detrás los registros que tuviere el *.reg, si los tiene y en cuyo caso, se hace actual el primer registro (listindex =0) que exigirá leer los registros en *.regdata asociados al registro *.reg actual.

Lo siento, pero no tiene sentido que pidas cambios a un proyecto, y luego operes con código de alguna versión anterior que ahora no encaja con los cambios de la versión actual...
No puedes coger código de una versión anterior y remplazarlo alegremente por el código de una nueva versión y esperar que funcione así, sin más (si fue ampliamente cambiado, como sucede en este caso). Tampoco conservo el código de las versiones previas.


Tienes que proceder con cierto orden y no mezclar versiones sin empaparte a fondo de los cambios que tiene una versión nueva respecto de la anterior (y desde luego al hacer cambios, conservar siempre copia del original, esto es, de la versión que funciona) y por tanto si al hacer cambios afectan o no y a qué afectan.
Esos detalles no suelen estar todos en la cabeza a un tiempo, especialmente cuando transcurre tiempo de olvidan, pero deberían constar en las especificaciones que uno debe haciendo previo al proyecto y mantener actualizado con los cambios. Como es un proyecto pequeño (y ni siquiera es para mi), yo no tengo necesidad de hacer tal especificación por escrito (susbsiste en mi cabeza mientras lo hago), y en cualquier caso la profusión de comentarios a los largo del código debería bastar al interesado...


« Última modificación: 1 Mayo 2022, 17:10 pm por Serapis » En línea

corlo

Desconectado Desconectado

Mensajes: 98


Ver Perfil
Re: Guardar list2 y leer list1
« Respuesta #51 en: 1 Mayo 2022, 18:07 pm »

Hola serapis

he hecho los cambios y ahora me dice error en crearnuevafacturacion

Código
  1.  
  2. Private Sub mnualmacen_Click(Index As Integer)
  3. 'Crear Nuevo Almacen
  4. Dim File As String
  5.  
  6.    Select Case Index
  7.        Case 0  ' Nueva facturación
  8.             File = InputBox("Elija el nombre del fichero para una nueva facturacón (no debe existir).", "Nueva Facturacion", "Nueva facturacion.dat")
  9.            If (Len(File) > 0) Then
  10.                File = AsegurarExtension(File, FILE_EXTENSION_FACTURA)
  11.  
  12.                If (CrearNuevaFacturacion(File) = True) Then
  13.                    Call Activar(True)
  14.  
  15.                Else
  16.                    Call Activar(False)
  17.                End If
  18.            Else
  19.                Call MsgBox("Proceso de creación de nueva facturación abortado. No se proporcionó un nombre", vbInformation, "Nueva facturación")
  20.            End If
  21.        Case 1  ' Leer fichero de facturación
  22.            Frmfile1.Show 1
  23.            If (Len(Frmfile1.File) > 0) Then
  24.                If (LeerFacturacion(App.Path & "\" & Frmfile1.File) = True) Then
  25.                    Call Activar(True)
  26.                Else
  27.                    Call Activar(False)
  28.                End If
  29.            End If
  30.  
  31.    End Select
  32. End Sub
  33.  
  34.  
  35.  
  36.  

If (CrearNuevaFacturacion(File) = True) Then


error argument not opcional en CrearNuevaFacturacion(file)


gracias




En línea

Serapis
Colaborador
***
Desconectado Desconectado

Mensajes: 3.357


Ver Perfil
Re: Guardar list2 y leer list1
« Respuesta #52 en: 1 Mayo 2022, 23:25 pm »

Sigues usando código de alguna versión anterior... Nuevamente estás usando una función vieja para llamar a la nueva. Te reclama el resto de parámetros que la llamada que expones no contemplaba en esa versión...

Así quedó el código de la última versión:
Código
  1. ' Crear nueva facturación,Abrir una existente.
  2. Private Sub mnuFile_Click(Index As Integer)
  3.    Dim File1 As String, File2 As String, NFacturaInicial As Integer
  4.  
  5.    Call CerrarCarrito
  6.  
  7.    Select Case Index
  8.        Case 0  ' Nueva facturación
  9.            File1 = InputBox("Elija el nombre del fichero para una nueva facturación (no debe existir).", "Nueva Facturacion", "Nueva facturacion" & FILE_EXTENSION_FACTURA)
  10.            NFacturaInicial = InputBox("Si la facturación debe empezar con un número específico, indique cual es a continuación:", "NuevaFacturación: Número de facturación inicial", "1")
  11.            If (Len(File1) > 0) Then
  12.                File1 = AsegurarExtension(File1, FILE_EXTENSION_FACTURA)
  13.                File2 = AsegurarExtension(File1, FILE_EXTENSION_FILES)
  14.                If (CrearNuevaFacturacion(File1, File2, NFacturaInicial) = True) Then
  15.                    Call ActivarInterfaz(True)
  16.                    Call FrmCarrito.Show(vbModeless)
  17.                Else
  18.                    Call ActivarInterfaz(False)
  19.                End If
  20.            Else
  21.                Call MsgBox("Proceso de creación de nueva facturación abortado. No se proporcionó un nombre", vbInformation, "Nueva facturación")
  22.            End If
  23.        Case 1  ' Leer fichero de facturación
  24.            FrmFile.Show 1
  25.            If (Len(FrmFile.File) > 0) Then
  26.                File2 = FrmFile.File
  27.                File1 = (App.Path & "\" & File2)
  28.                File2 = App.Path & "\" & AsegurarExtension(File2, FILE_EXTENSION_FILES)
  29.                If (ListarFacturacion(File1, File2) = True) Then
  30.                    Call ActivarInterfaz(True)
  31.                    Call FrmCarrito.Show(vbModeless)
  32.                Else
  33.                    Call ActivarInterfaz(False)
  34.                End If
  35.            End If
  36.    End Select
  37. End Sub
  38.  
Como se ve, la función (que ni se llama igual, porque procede del nombre de otro menú), cuando llama a la función CrearFacturación precisa más parámetros...
Diríase que no sabes usar el editor de código para siquiera consultar que parámetros requiere la función a invocar, ni que entiendas los errores que te está marcando sobre la marcha la ejecución del código...

Me pregunto si llegaste a descargar, utilizar o intentar comprender el código de la última versión que te puse hace ya casi dos meses (mensaje 34 del hilo).
...
Aquí la descarga, por si lo quieres ir probando:
https://workupload.com/file/9rRxdbcR2wv 76Kb. aprox. comprimido (incluye los ficheros  de ejemplo).
...


Por favor, no me insistas en que te solucione código que quedó solucionado. O usas enteramente una versión previa o enteramente la nueva versión. Los cambos (como te dije entonces), eran tan profundos que exigió retocar prácticamente todo, creo recordar que no quedó ninguna ventana sin que quedara afectada por los cambios. Yo me molesté en actualizar todas esas ventanas con su código para que los cambios que principalmente se solicitaban no dejarán cojo (sin funcionar o malfuncionando) el resto del programa que se vió afectado, además también me tomé la molestia de comentar los cambios que afectaron a cada uno de los módulos de código.

Yo no tengo ninguna forma de saber que cambios has hecho, ni que has tomado de una versión u otra, ni siquiera saber sobre qué versión estás trabajando... ni me siento obligado a resolver tu estulticia una y otra vez, si decides mezclar código de diferentes versiones sin pararte antes a considerar previamente qué implica hacer cambios... porque entonces esto nunca termina.

Es como si alguien comprara un vehículo, le cambia varias piezas de un motor por otro de un vehículo viejo que tenía y espera que el fabricante del nuevo le resuelva los problemas generados de dichos cambios, incluso aunque el fabricante fuera el mismo de ambos vehículos. Incluso aunque por cortesía el fabricante te diera indicaciones de los 'posibles' problemas, si tu sigues haciendo cambios de piezas.  Un fabricante vende su vehículo tal cual viene, cualquier cambio y que deje de funcionar, ahí el fabricante (además de anular su garantía) te dirá que los cambios que hagas serán bajo tu cuenta y riesgo...

Igualmente yo de digo que tú como programador debes ser capaz de resolver los problemas que te surjan cuando acometas cambios en un código que era plenamente funcional. Te solucionaría exclusivamente si algo no funcionara correctamente en el código de la última versión, solo porque aún lo conservo y no me costaría dar con cualquier posible error (en el caso de que no fueras capaz de solucionarlo), pero me desentiendo de resolver tus problemas por hacer cambios (y menos tirando de versiones anteriores, o pero mezcla de ellas) ni de acometer nueva funcionalidad.

Lo que es prestar ayuda en la compresnsión, explicación y/o dando código, creo que está más que satisfecho, el resto es dependiente de tus capacidades. Incluso el código que te he dado, aunque es plenamente funcional no es óptimo, pues te lo hice a modo de ejemplo mínimo para operar con ficheros, lo ideal era reconvertirlo para usar con clases y tablas hash, pero que dadas tus limitaciones entiendo que te quedases sin acometer tales cambios.
« Última modificación: 1 Mayo 2022, 23:38 pm por Serapis » En línea

Páginas: 1 2 3 4 5 [6] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Leer, Guardar, Cargar .INI
.NET (C#, VB.NET, ASP)
SγиtαxEяяoя 7 5,341 Último mensaje 26 Mayo 2013, 19:39 pm
por Eleкtro
problema leer y guardar datos..
Programación C/C++
adrian123321 2 2,459 Último mensaje 29 Agosto 2013, 08:57 am
por do-while
guardar y leer objetos en archivos binarios
Java
victor garay 1 3,692 Último mensaje 17 Abril 2015, 06:51 am
por Usuario Invitado
Leer fichero y guardar en variables
Programación C/C++
Joaqqinn 6 4,739 Último mensaje 13 Enero 2016, 23:43 pm
por Orubatosu
pasar informacion de list1 a list2
Programación Visual Basic
corlo 2 3,023 Último mensaje 27 Febrero 2019, 20:27 pm
por corlo
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines