Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Serapis

#71
Para eso existen las colecciones...

...donde el único nombre preciso es el que se otorga a la colección, luego cada elemento puede ser simplemente referido por su índice (caso de un array, por ejemplo), o su posición/dirección (caso de árboles, por ejemplo), o por un atributo adjunto al valor (cuando se permitan valores repetibles), caso por ejemplo de tablas hash...

Todos los lenguajes poseen tipos de datos que permiten usar colecciones homogéneas (un mismo tipo de datos) e incluso heterogéneas (diferentes tipos de datos, como si fuera un saco').
#72
Cita de: FFernandez en 28 Noviembre 2021, 18:41 PM
Tienes la formula ............   y el inicio de la secuencia.
Lo que busco, es que pongáis la forma de llegar a esa fórmula.
Parece redundante, pero no puedo anticiparme a nada, sino no me vais a entender.
Las series es un tema resuelto. Hay series aritméticas y series geométricas.
Dada una razón y los valores extremos, pueden hallarse 'n' términos intermedios. Intercambiando parámetros, esto es despejando... pueden calcularse unos valores dados otros. Calcular por tanto el término 99 de la serie, el 6541 o uno que precisa 100 dígitos para expresarlo, es solo una cuestión de tiempo de cálculo...
 
Cita de: FFernandez en 28 Noviembre 2021, 18:41 PM
Encontrar una secuencia distinta con esos 4 primeros términos para mi seria una tarea Titánica.  
Es estéril perder tiempo en eso. Entiendo que quien no tenga una base matemática mínima tenga que andar tirando de tentativas.
https://es.wikipedia.org/wiki/Serie_aritm%C3%A9tica
https://es.wikipedia.org/wiki/Serie_geom%C3%A9trica


Cita de: FFernandez en 28 Noviembre 2021, 18:41 PM
Rastrear Internet solo te ayudara en la forma de llegar a la formula V=n(n+1)/2 que descubrió GAUSS.
Qué rastrear ni qué niño muerto...?.

La web que te proporciono, resulta útil para hallar series (conocidas y con alguna '¡importancia') de las cuales solo tienes unos valores dados de la serie... te facilita info sobre varias series que cumplan ese criterio mínimo, es habitual que haya más de una que lo contenga en su secuencia.
Luego tu verás cual de ellas se ajusta al criterio que estés buscando (si es alguna de ellas y si es que estás buscando).
La info dada para una serie, te cita los autores que la han datado y siempre una fórmula (en realidad suelen darse varias) para hallar los valores de la serie, es muy probable que más de 1 autor hayan llegado a la misma serie desde diferentes perspectivas y que incluso la hayan resuelto de modo distinto (pero equivalente, lógicamente).

Si simplemente para ti es un mero entretenimiento, empieza por ahí, y buenaventura. No acostumbro a perder tiempo en tonterías, prefiero hacerlo en cosas donde alguien lo necesite, y no donde simplemente 'le divierta'.



p.d.: en resumen, que tiene esto de 'criptografía'?. Entiendo que para un mono una raíz cuadrada sea criptografía.


#73
Redes / Re: duda sobre las antenas wifi
28 Noviembre 2021, 17:21 PM
Cita de: inma55 en 28 Noviembre 2021, 12:31 PM
pero a ver...cuanto mas caro mejor chip traerá...
Te vendo mi móvil por 15.000 euros.
Ya me dirás tú si el precio cuadra con que sea mejor.

Por otro lado, más que tf. debes interesarte por la red wifi, por muy bueno que sea el móvil tiene un alcance limitado.
Es la red, la que debe tener alcance, y tu dispositivo el que debe estar dentro del radio de alcance. Que la antena de tú móvil sea 'mierdosa', solo implica que clase de obstáculos límitan la conexión a pesar de estar dentro del alcance del radio de la antena.

Lo que necesitas es que tu router (suponiendo que sea tuyo), tenga un alcance mayor. A veces lo tienen pero no está configurado al máximo (yo por ejemplo en el router de mi casa lo tengo límitado al mínimo, justo para que cubra mi casa, para qué ponerlo al máximo y alcanzar las casas de 3/4 vecinos más en el radio?). Probablemente no todos los fabircantes den opción de configurarlo (no conozco todos los fabricantes ni modelos, obviamente).

Para zonas rurales, lo ideal es usar antenas específicas al uso, algunas puedne dar un alcance de hasta 2 km. claro que hay que saber si el precio encaja en tu bolsillo, pero las hay más modestas que lógicamente tiene un precio más asequible. Hace unos años había que pensárselo bien... hoy son más asequibles.

https://www.google.com/search?q=antenas+de+largo+alcance+wifi
#74
Si miras detrás de la carcasa del dispositivo, tienen que venir los datos.

En dispositivos muy pequeños como el tf. móvil, podrás recurrir a las especificaciones que se localizan en el manual con el que se entrega cada dispositivo cuando se vende. Y si no lo conservas ya, busca la web del fabricante, dentro de ella el dispositivo y lee sus especificaciones. En el supuesto de un dispositivo viejo que el fabricante ya lo haya retirado de línea, con suerte puede aparecer por la red, busca 'mi marca de dispositivo, mi modelo, especificaciones'.

Si la batería es extraíble, pués vendrá en la carcasa de la propia batería que podrás ver cuando la extraigas. Lo mismo si no es extraíble, pero tiene una carcasa que sí es extraíble y la batería aparece a la vista.
#75
De entrada 4 números, no son representativos de una única serie...
Luego, el enfoque no está adecuadamente planteado, no se entiende bien qué es lo que buscas.

En cualquier caso cuando quieres modos de resolver una serie, existe en internet un sitio especializado en ello, basta meter unos números consecutivos de la serie y te localiza y muestra las entradas recogidas... pincha en cada una para ir a los detalles. para cada serie recogida se documenta bien (y abundante):
http://oeis.org/search?q=1%2C3%2C6%2C10&language=english&go=Search
#76
Siguiendo la normalización de la base de datos, prácticamente te resuelve el asunto:
https://es.wikipedia.org/wiki/Normalizaci%C3%B3n_de_bases_de_datos
#77
Pues vaya M13RD@ de 'antivirus'... solo contiene los ficheros del proyecto más el fichero de ejemplo que desde luego no es un ejecutable.

Subirlo a otro lado, no creo que solvente el asunto... el fichero zip es el mismo, quien lo detiene es ese tonto-antivirus (no la web), que desde luego parece inútil.

Mira de desactivar el antivirus ese (eso es de vodafone, no?) , descárgalo y luego si quieres puedes pasarlo por virustotal, pero vamos con abrir el zip, se ve que no contiene nada 'malicioso'. No olvides volver a activar ese antivirus si lo encuentras útil...

En esta pagina te viene cono activarlo y desactivarlo:
https://www.adslzone.net/operadores/vodafone/vodafone-secure-net/

¿Por lo que leo (un vistazo rápido) es para móviles, porqué no lo descargas desde el PC?.

p.d.: Me edito...
Citar
Si en cualquier momento queremos desactivar el servicio, desde cualquier dispositivo 1 abrimos una ventana de nuestro navegador favorito,
2 pulsamos sobre el icono de Vodafone Secure Net, seleccionamos el botón de ajustes
3 y en la parte inferior de la página
4 pulsamos sobre la opción Desactivar.
#78
Cita de: corlo en 26 Noviembre 2021, 22:00 PM
tu trabajas con funciones , me has cambiado la manera de trabajar, tengo que seguir  con lo que dices tu, yo ya no puedo trabajar con lo que hacia yo.
Ok... Ayer al final no me puse con él.
...pero lo acabo de terminar ahora y probar por encima... he cambiado algunos detalles (por ejemplo el orden en que muestran los campos en el listbox) y corregido algunas diferencias (por ejemplo, en el registro el numero de ticket estaba definido como entero, y la busqueda suponía en long, lógicamente no lo encontraría de esa manera).

Te comparto del proyecto completo... incluye un fichero de ejemplo con algunos registros guardados.
Lo modificas a tu necesidad, pero recuerda que si cambias la estructura del registro (type...), elimina el  fichero y crea uno nuevo. Por ejemplo el campo 'producto' es demasiado brece (12 caracteres), si pongo 'Destronilladores' no cabe ni mucho menos 'juego de ...' 30-40 caracteres, estaría bien.
Nota que la búsqueda por artículo exige que sea exacta (salvando la capitalización), sería adecuado modificarlo o añadir un parámetro para localizar por similitud (like, o contiene parcialmente...).

Enlace de descarga:
https://workupload.com/file/AHRpXupVQQz  11Kb. aprox. descomprimido 35.5kb, aprox.

No hay mucho que explicar, revisa el código ejecutándolo paso a paso, para entender cada cosa, céntrate cada vez en una sola cosa... manejo de ficheros, lectura/escritura de datos, edición de un registro, validaciones, etc...



Si necesitas alguna aclaración, pregunta.
#79
Esperaba que pudieras deducir que se trata de botones...

No es necesario poner código para los optionbuttons, además deben formar un array, esto es deben tener el mismo nombre pero uno con índice 0 y otro 1, así su índice ya refiere su valor sobre el método de pago.

La función 'getmetodopago', si te fijas bien en lo que hace, simplemente devuelve un string, en base al valor recibido... eso solo se usa para convertir el valor del método de pago en el string, que luego se va a introducir al listbox (pasar al listbox, 0 ó 1, no dice nada útil ni comprensible).

Creo que estás más verde aún de lo que parece en cuanto al dominio no solo del lenguaje sino de claridad de ideas respecto de la programación.

Normalmente 'el conocimiento' y 'la inteligencia' (las capacidades intelecturales) es algo innato, que al programar uno debe saber 'traducir' y respecto del lenguaje es algo que sí o sí uno debe aprender desde cero (esto pasa con cualquier nuevo lenguaje que uno quiera aprender). Quiero decir que la programación no es un invento, sino el resultado del intelecto, aplícalo y la programación será más fácil, si partes de la idea de que la programación es un invento de alguien, entonces te será difícil aplicarte, porque parece exigir aprender o ponerte en el pellejo de quien 'lo inventó'. Eso es cierto para el lenguaje, que suele obedecer en ocasiones al capricho de su diseñador aunque en buena medida es el resultado de meditar y madurar ideas...
Si intentas aplicar lógica con inteligencia a la programación, el resto sólo depende de la profundidad en que conozcas el lenguaje en el que pretendes escribirlo.

Bien, respecto del asunto, en realidad anoche lo dejé más avanzado, de lo que te envié, en un momento, simplemente me pareció que era preferible copiarlo y guardarlo para enviártelo así y desde ahí intentaras por tu cuenta a modo de ejercicio completar lo que faltara, para ver como lo resolvías.
Los botones de la interfaz, por ejemplo los moví a un menú, los textbox a una ventana para editar el registro, los valores de búsqueda a otra ventana para lo mismo, definir los parámetros de búsqueda, cambié alguna cosa más... y deje para hoy solamente la activación y desactivación de los botones (ahora en el menú), según correspondan... lo terminaré más tarde, después de cenar. Te comentaré por aquí por encima, y subiré copia a alguna página de descarga...
#80
La instrucción LenB(variable), devuelve la cantidad de bytes que contiene esa variable, así como Len(string) devuelve la cantidad de caracteres (no necesariamente se corresponde con la cantidad de bytes).
en cualquier caso, cuando tengas dudas, posicionar el cursor encima de la instrucción (o cualquier parte de la sintaxis de vb6), pulsa la tecla F1 y te lleva a la ayuda, donde tes explica su cometido y puede incluso contener algún ejemplo.

Por cierto... esa función tiene un pequeño error del que me acabo de dar cuenta, te comento por encima:
Lo habitual es que al comienzo de ficheros con un determinado formato, exista una cabecera (de tamaño fijo generlamente o al menos conocido antes de escribir lo que venga detrás), en este caso la cabecera está compuesta por un único dato: 'NumRegistros', que al ocupar 4 bytes (del long de vb6), debe añadirse para calcular la posición absoluta de lectura/escritura de comienzo de u registor dado, es decir el primer registor debe comenzar en la posición 5 (vb6 considera que un fichero comienza siempre en la posición 1).

Citar
Private Sub PosicionarRegistro(ByVal Numregistro As Long)
   If (Abierto = True) Then
       Seek (Canal), (5 + ((Numregistro-1) * LenB(reg1)))
   End If
End Sub
--------------------------------------------------------------------------

Tu segunda duda:
Citarpara activar o desactivar ... lo que proceda
Lo razonable es que hayas elementos en la interfaz que estén 'sincronizados' con determinados estados... por ejemplo el botón 'guardar' registro debería estar desactivado mientras no se haya abierto el fichero.
Si ni siquiera existe un fichero, es adecuado que esté habilitado un botón 'Crear nueva Factuación' (imagina por ejemplo un fichero por cada mes), que cierre el previo, vacíe el listado y los textbox, crea y abre un nuevo  fichero y entonces activa los botones de añadir registro y buscar y cerrar, etc...
Siempre se puede añadir una comprobación dle tipo:
si Abierto=true luego
  ...
fin si

En el código (por ejemplo) del botón guardar registro, peor lo ideal es que si no se puede guardar, ese btón no estuviere activo.
---------------------------------------

...me edito, para ponerte el código... estará sin terminar al completo y sin provar ya que va siendo tarde, mira a ver si completas lo que falta (el código de los botones) y alguna pequeña función...

Nota que te pongo todo de nuevo, porque he cambiado alguna cosa... la función abrir, ahora debe abrir bajo dos condiciones, cuando se lee un fichero existente y cuando se pretende crear un nuevo fichero (que no debe existir)...
Las funciones añadidas, están al final... falta el código de los botones y alguna función más para completarlo.
Abajo pongo una capturas de como se vería la interfaz y vale por hoy.

Código (vb) [Seleccionar]

Private Enum MetodosDePago
  PAGO_AL_CONTRADO = 0
  PAGO_CON_TCREDITO = 1
End Enum

Private Type RegCompra
   NumTicket                       As Integer      ' 1
   FechaCompra                     As Date         ' 3
   MetodoDePago                    As Byte         ' 11
   Alineacion                      As Byte         ' 12 nada solo hace que el registro sea una cantidad par, para ser más efectivo en lecturas

   Producto                        As String * 12  ' 13
   PrecioUnidad                    As Single       ' 25
   Cantidad                        As Integer      ' 29
   SubTotal                        As Single       ' 31
End Type                                            ' total: 34 bytes por registro

Private Const DIR_COMIENZO_REGS     As Long = 9     ' 1+4+4

Private NumRegistros                As Long
Private AutonIncRegs                As Long
'
Private Canal                       As Integer     ' Número de canal de comunicación con el fichero.
Private reg1                        As RegCompra   ' para leer registros
Private reg2                        As RegCompra   '  para escribir registro, así diferenciados, será más difícil equivocarnos




Private Sub ComNuevaFacturacion_Click()
   If (Len(TxtFile.Text) > 0) Then
       Call CrearNuevaFacturacion(TxtFile.Text)
   End If
End Sub

Private Sub ComAbrirFacturacion_Click()
   Form2.Show 1
   
   If (Len(Form2.File) > 0) Then
       If (LeerFacturacion(App.Path & "\" & Form2.File) = True) Then
           Call Activar(True)
       Else
           Call Activar(False)
       End If
   End If
End Sub

Private Sub ComBuscar_Click()
   '
End Sub

Private Sub ComEditarRegistro_Click()
   '
End Sub

Private Sub ComGuardarRegistro_Click()
   '
End Sub

Private Sub ComRetirarRegistro_Click()
   '
End Sub

Private Sub ComSalir_Click()
   '
End Sub

Private Sub List1_Click()
   If (Abierto = True) Then
       Call PosicionarRegistro(List1.ListIndex + 1)
       Get #Canal, , reg1
       Call TrasferirRegToTextbox(reg1, vbTab)
   End If
End Sub


' ------------ Fin interfaz ------------------

Private Function LeerFacturacion(ByRef Ruta As String) As Boolean
   Dim k As Integer

   If (Abrir(Ruta) = True) Then
       Get #Canal, 1, NumRegistros

       For k = 1 To NumRegistros
           Get #Canal, , reg1
           Call List1.AddItem(SerializarRegistro(reg1))
       Next
       ' Ahora si se quiere puede leerse de nuevo el primer registro para transferirlo a los textbox...
       List1.ListIndex = 0 ' para ello delegamos en el código que pondremos al listbox...
   End If
End Function

Private Sub TrasferirRegToTextbox(ByRef R As RegCompra)
   With R
       txtNumTicket.Text = .NumTicket
       txtFechaComprar.Text = CStr(.fecha)
       optMetodoPago(.MetodoDePago).Value = True  ' 2 controles option con indices 0 y 1
       'cheMetodoPago.value = .MetodoDePago   ' también vale un checkbox, que cambie su 'caption' según su valor, alternando entre 'Pago al contado' o 'Pago con Tarjeta de crédito'.
       txtProducto.Text = .Producto
       txtPrecioUnidad.Text = CStr(.PrecioUnidad)
       txtCantidad.Text = CStr(.Cantidad)
       txtSubtotal.Text = CStr(.SubTotal)
   End With
End Sub

Private Sub PosicionarRegistro(ByVal Numregistro As Long)
   If (Abierto = True) Then
       Seek (Canal), (DIR_COMIENZO_REGS + ((Numregistro - 1) * LenB(reg1)))
   End If
End Sub

Private Function SerializarRegistro(ByRef Registro As RegCompra, ByVal Separador As String) As String
   With Registro
       SerializarRegistro = CStr(.NumTicket) & Separador & CStr(.FechaCompra) & _
              Separador & GetMetodoPago(.MetodoDePago) & Separador & .Producto & _
              Separador & CStr(.Cantidad) & Separador & CStr(.PrecioUnidad) & Separador & CStr(.SubTotal)
   End With
End Function

Private Function GetMetodoPago(ByVal Metodo As MetodosDePago) As String
   If (Metodo = PAGO_AL_CONTRADO) Then
       GetMetodoPago = "Contado"
   Else
       GetMetodoPago = "T. Credito"
   End If
End Function


Private Function ExisteFichero(ByRef Ruta As String) As Boolean
   Dim j As Integer, File As String

   j = InStrRev(Ruta, "\")
   If (j > 0) Then
       File = LCase$(Right$(Ruta, Len(Ruta) - j))
       ExisteFichero = (LCase$(Dir(Ruta, vbNormal)) = File)
   End If
End Function

' Abre un fichero que YA EXISTE: Cuando se solicita leer la facturación de uno.
' Abre un fichero que NO EXISTE: Cuando se trata de crear una nueva facturación.
Private Function Abrir(ByRef Ruta As String, Optional ByVal NoDebeExistir As Boolean = False) As Boolean
   If (Abierto = True) Then Call Cerrar

   If (ExisteFichero(Ruta) = False) Then
       If (NoDebeExistir = False) Then Exit Function
   End If
   
   Canal = FreeFile
   On Error GoTo FalloApertura
   Open Ruta For Binary As #Canal

FalloApertura:
   If (Err.Number > 0) Then
       Call MsgBox("Error al intentar abrir el fichero en la ruta:" & vbCrLf & Ruta & vbCrLf & Err.Description, vbInformation, "Error de apertura:")
       Err.Clear
   Else
       Abrir = True
   End If

   On Error GoTo 0 ' hay que desactivar el controlador de errores, si no, cualquier error posterior cae en este interceptador (si es el último activo)...
End Function

Public Property Get Abierto() As Boolean
   Abierto = (Canal > 0)
End Property

Private Function Cerrar()
   Close #Canal
   Canal = 0
   NumRegistros = 0

   ' desactivar de la interfaz lo que proceda...
End Function


' -------------------------------------------------
' -------- NUEVO DESDe AQUI ---------------
'--------------------------------------------------
' Index refiere al enésimo registor en el fichero.
' Si es -1 refiere al último, lo adecuaod cuando se añade.
' Si es entre 1 y NumRegistros, señala que es un registro que se ha editado...
Private Sub GuardarRegistro(ByRef R As RegCompra, Optional ByVal Index As Long = -1)
   If (R.NumTicket = 0) Then
       AutonIncRegs = (AutonIncRegs + 1)
       R.NumTicket = AutonIncRegs
   End If

   '
   If (Index = -1) Then
       NumRegistros = (NumRegistros + 1)
       Index = NumRegistros
   End If
   
   Call PosicionarRegistro(Index)
   Put #Canal, , R                                 ' Guarda el registro
   Put #Canal, 1, NumRegistros                     ' Guarda la cantidad de registros
   Put #Canal, , AutonIncRegs                      ' Guarda el valor de autoincrmeento (es un valor único).
End Sub

Private Function CrearNuevaFacturacion(ByRef NombreFile As String) As Boolean
   Dim Ruta As String
   
   Ruta = App.Path & "\" & NombreFile
   If (Abrir(Ruta, True) = True) Then
       NumRegistros = 0: AutonIncRegs = 0
       Put #Canal, 1, NumRegistros                 ' Guarda la cantidad de registros
       Put #Canal, , AutonIncRegs                  ' Guarda el valor de autoincrmeento (es un valor único).
   
       CrearNuevaFacturacion = True
   Else
       MsgBox "Parece que el fichero que intenta abrir ya existe, elija otro nombre (o bien ocurrió un error)..."
   End If
End Function

' Numreg: Permite seguir buscando más artículos a partir del previo que se encontró...
Private Function BuscarArticulo(ByRef Producto As String, Optional ByRef NumReg As Long = 0) As Boolean
   Dim k As Long, ptr As Long, inc As Long, Articulo As String * 12
   
   If (NumReg < NumRegistros) Then
       NumReg = (NumReg + 1)
       If (NumReg > 1) Then
           Call PosicionarRegistro(NumReg)
           ptr = Seek(Canal) + 12
       Else
           ptr = (DIR_COMIENZO_REGS + 12)                  ' Dir de comienzo de registros + desplazamiento al campo soliicitado.
       End If
       
       Producto = LCase(Producto)
       inc = LenB(reg1)
       For k = NumReg To NumRegistros
           Get #Canal, ptr, Articulo
           
           If (LCase$(Articulo) = Producto) Then
               Get #Canal, ptr - 12, reg1
               BuscarArticulo = True
               Exit For
           End If
           ptr = (ptr + inc)
       Next
       
       NumReg = k
   End If
End Function

' En cada fichero cada compra tiene un numero de ticket único (no hay dos repetidos, como si puede pasar con el nombre del artículo).
Private Function BuscarTicket(ByVal Ticket As Long) As Boolean
   Dim k As Long, ptr As Long, inc As Long, nTicket As Long
       
   ptr = DIR_COMIENZO_REGS                     ' Dir de comienzo de registros + desplazamiento al campo soliicitado=0.
   inc = LenB(reg1)
   For k = 1 To NumRegistros
       Get #Canal, ptr, nTicket
       
       If (LCase$(nTicket) = Ticket) Then
           Get #Canal, ptr, reg1
           BuscarTicket= True
           Exit For
       End If
       ptr = (ptr + inc)
   Next
End Function



Yo elegiría un control flexgrid en vez de un listbox, que ya tiene sus columnas y tal, pero es más complejo de manejar para empezar...
Nota que la interfaz de momento la dejo así, solo para que puedas captar todos los detalles que contiene. En realidad cosas como los textbox deben ir a una ventana aparte donde se editen o creen... pero así no te hago esperar si ves todo lo que contiene e intentas por tí mismo completarlo.