• Miércoles 12 de Marzo de 2025, 12:31

Mostrar Mensajes

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


Mensajes - DiabloRojo

Páginas: 1 ... 6 7 [8] 9
176
Visual Basic 6.0 e inferiores / Re: Insertar De Una Tabla A Otra Por Sql
« en: Miércoles 20 de Octubre de 2004, 21:08 »
Qué tal?
Pues no veo la cláusula FROM en ninguna parte de tu consulta. Imagino que debe ser eso. Por cierto, ¿con qué manejador de base de datos estás trabajando?.


DiabloRojo

177
Visual Basic 6.0 e inferiores / Re: Insertar De Una Tabla A Otra Por Sql
« en: Miércoles 20 de Octubre de 2004, 18:48 »
Hola.
La consulta tendría esta forma:

INSERT INTO NombreTabla ( lista campos) SELECT lista tabla.campo FROM lista tablas WHERE condiciones

Por ejemplo:

INSERT INTO resultados (Nombre, Apellido, NotaF) SELECT Alumno.Nombre,Alumno.Apellido,Notas.NotaF FROM Alumno,Notas WHERE Alumno.Id=COD and Notas.Id=COD

178
Visual Basic 6.0 e inferiores / Re: Clausula In No Me Funciona ¿?
« en: Miércoles 20 de Octubre de 2004, 18:26 »
Hola MindEye.
Estuve releyendo con más detenimiento tu planteamiento. Te recomiendo que quites ese campo (usuarios) de la tabla y que crees otra tabla con los campos siguientes:

IdRegistro, IdUsuario, FechaAcceso y HoraAcceso.

(yo llamo a esta tabla SegAcces)

Estoy suponiendo que tienes una tabla donde almacenas los datos de los usuarios y que cuenta con un campo IdUsuario, así mismo, que en la tabla que mencionas posees un campo que identifique a cada registro y que se llame IdRegistro. Explico:

-IdRegistro sería el identificador del registro al cual ha accedido un usuario -que se encuentra en tu tabla Tabla-.
-IdUsuario pues el identificador del usuario -que estaría en una hipotética tabla Usuarios-.
-FechaAcceso sería la fecha en la cual se realizó el acceso al registro -que pertenece a la tabla que te aconsejo crees-.
-HoraAcceso la hora en la cual se realizó el registro -que pertenece a la tabla que te aconsejo crees-.

Por supuesto tu podrás añadir más campos en esta tabla según los necesites.

Imagino que en algún lugar de tu aplicación posees alguna forma para seleccionar a un usuario de ahí tomarás el valor "Valor" de IdUsuario y puedes hacer una consulta como la que sigue:

SELECT * FROM Tabla WHERE IdRegistro IN (SELECT IdRegistro FROM SegAcces where IdUsuario<>Valor)

otra forma sería:

SELECT * FROM Tabla WHERE IdRegistro NOT IN (SELECT IdRegistro FROM SegAcces where IdUsuario=Valor)


Si te das cuenta esta nueva tabla es un enlace entre los usuarios y los registros.

Espero haber sido suficientemente claro y haber ayudado en algo.


DiabloRojo

179
Visual Basic 6.0 e inferiores / Re: Clausula In No Me Funciona ¿?
« en: Martes 19 de Octubre de 2004, 13:27 »
Ok. Pensé que usuarios era otra tabla. Si puedes mandar la estructura de las tablas involucradas tal vez sea más fácil detectar el error o ver alguna forma de resolver tu problema.
La verdad no entiendo muy bien... ¿Dices que en el mismo campo guardas todos los datos de las personas que han visitado ese registro?. Si es así puedes tener un error de Normalización... Recuerda que los datos contenidos en cada campo deben ser atómicos (algo así como partículas individuales e independientes).
Pero lo que te dije antes, manda las estructuras de la/las tabla(s) involucrada(s) para poder ver mejor lo que está pasando.


DiabloRojo

180
Visual Basic 6.0 e inferiores / Re: Clausula In No Me Funciona ¿?
« en: Lunes 18 de Octubre de 2004, 21:21 »
Qué tal MindEye?

Creo que puedes hacerlo de dos formas:

1.- SELECT * FROM tabla WHERE [Id Usuario] <> Valor

2.- SELECT * FROM tabla WHERE [Id Usuario] NOT IN (Valor)

Donde Valor es el valor que quieres que tu búsqueda omita. Prueba y dime si alguna de las dos formas te funcionó.

NOTA: La cláusula IN arroja como resultado un número n de registros cuyo criterio de búsqueda es un CONJUNTO de valores proporcionados por ti. Por ejemplo:

SELECT * FROM tabla1 WHERE pais IN ('EEUU','MEXICO','CANADA')

Devuelve aquellos registros cuyo campo país sean EEUU, MEXICO o CANADA.


DiabloRojo

181
Visual Basic 6.0 e inferiores / Re: Me Estoy Volviendo Loco!!!
« en: Lunes 18 de Octubre de 2004, 20:48 »
Qué tal mi69?
La verdad no estoy muy al corriente con ADO pero lo que veo con tu código es que la sentencia SQL que utilizas la almacenas en una variable de tipo String (que precisamente llamas SQL) y no la vinculas con ninguno de los objetos proporcionados por ADO; mediante los métodos Open, Execute o CommandText, por ejemplo.

Espero haberte ayudado en algo.


DiabloRojo

182
Qué tal Gallagher?
Supongo que puedes quitar el MDAC (Microsoft Data Access Componets) con el Agregar y Quitar programas que aparece en el panel de control.
Puedes indicar cuales son las diferencias entre el MDAC 2.8 y el MDAC 2.5?

DiabloRojo

183
Crystal Reports / Crystal Reports 9
« en: Domingo 17 de Octubre de 2004, 15:00 »
Hola foro.
Pues mi consulta es esa... ¿Dónde puedo conseguir manuales o tutoriales del CR9?.
De antemano gracias por la ayuda.

DiabloRojo.

184
Visual Basic 6.0 e inferiores / Re: Crystal Reports 9
« en: Sábado 16 de Octubre de 2004, 13:37 »
Muchas gracias avaguin. Procederé a instalarlo entonces.

185
Visual Basic 6.0 e inferiores / Crystal Reports 9
« en: Sábado 16 de Octubre de 2004, 04:39 »
Qué tal foro?
Quisiera saber si se puede utilizar el crystal Reports 9 con Visual Basic 6.0 ya que he estado viendo los requisitos de sistema que pide y veo que hace referencia es a Visual Basic.Net. ¿Hay alguna forma de usarlo con VB6.0?

Saludos.

DiabloRojo.

186
Visual Basic 6.0 e inferiores / Re: Ayuda Sobre Mysql
« en: Miércoles 6 de Octubre de 2004, 12:59 »
Hola migue.
Ya probaste utilizando la función Shell de VB? Creo que también te serviría la función API ShellExecute.

Espero haberte ayudado algo.


DiabloRojo.

187
Visual Basic 6.0 e inferiores / Re: Mostrar Un Formulario A Partir De Un String
« en: Lunes 20 de Septiembre de 2004, 21:55 »
Qué tal redram?
Una forma en la que puedes hacer lo que dices es usando un procedimiento como el siguiente:

Código: Text
  1.  
  2. Private Sub MuestraForm(NomForm As String)
  3.    Dim MiForm As form
  4.    '
  5.    Select Case NomForm
  6.       Case &#34;frmSegundo&#34;
  7.          Set MiForm = New frmSegundo
  8.      
  9.       Case &#34;frmTercero&#34;
  10.          Set MiForm = New frmTercero
  11.      
  12.       Case &#34;frmCuarto&#34;
  13.          Set MiForm = New frmCuarto
  14.     End Select
  15.        
  16.     Load MiForm
  17.     MiForm.Show
  18. End Sub
  19.  
  20.  
  21.  

En el código anterior se supone que existe en el proyecto tres formularios llamados (propiedad name): frmSegundo, frmTercero y frmCuarto. Dependiendo del caso podrías impedir que se cargue un formulario más de una vez.
Espero que te sea de utilidad.

DiabloRojo

188
Visual Basic 6.0 e inferiores / Re: Ayuda Sobre Crystal Report
« en: Jueves 16 de Septiembre de 2004, 15:07 »
Hola crow7827.
En los discos de instalación del VB puedes encontrar el Crystal Reports 4.5 -si mal no recuerdo en el disco 3-. No es lo mas actual pero por algún lado hay que empezar ¿no?.


DiabloRojo

189
Visual Basic 6.0 e inferiores / Re: Uso Del Tipo Date
« en: Miércoles 15 de Septiembre de 2004, 14:53 »
sirespi.
Primero debo decirte que en el ejemplo anterior que te dí hay un error NO debes usar la función Now sino la función Time.
Aquí te mando un ejemplo de cómo hacer para que el Beep suene a una hora determinada. Crea un proyecto nuevo añade dos TextBox (Text1 y Text2), un Label, dos CommandButton y un control timer. Copia el siguiente código:

Código: Text
  1.  
  2. ' Sección general de declaraciones
  3. Dim HorInicio As Date
  4. Dim HorFinal As Date
  5. Dim Sonar As Boolean
  6. Dim hora As Date
  7.  
  8. Private Sub Command2_Click() 'Detener
  9.    Sonar = False
  10. End Sub
  11.  
  12. Private Sub Command1_Click() 'Aceptar
  13.    '
  14.    ' Los datos introducidos en Text1 y Text2
  15.    ' deben tener el formato hh:mm:ss
  16.    HorInicio = CDate(Text1.Text)
  17.    '
  18.    HorFinal = CDate(Text2.Text)
  19.    '
  20.    Sonar = True
  21.    '
  22. End Sub
  23.  
  24. Private Sub Form_Load()
  25.    Timer1.Interval = 2000 'Por lo general se usa 500
  26.    Timer1.Enabled = True
  27. End Sub
  28.  
  29. Private Sub Timer1_Timer()
  30.    Label1.Caption = Str(Time)
  31.    '
  32.    hora = CDate(Format(Time, &#34;hh:mm:ss&#34;)) ' Para eliminar la partícula a.m/p.m
  33.    '
  34.    If (Sonar = True) Then    
  35.       If (hora &#62;= HorInicio And hora &#60;= HorFinal) Then
  36.          Beep
  37.          'Print &#34;Hola&#34;
  38.       End If
  39.    End If
  40. End Sub
  41.  
  42.  

Comentarios:
-Por cuestiones de practicidad no incluyo validaciones así que te debes asegurar de proporcionar datos correctos.
-Text1 corresponde a la hora en que deseas que el Beep comience a sonar.
-Text2 corresponde a la hora en que deseas que el Beep deje de sonar.
-Text2 debe ser mayor a Text1.
-Command2 detiene el Beep.
-El control timer se utiliza para realizar o ejecutar fragmentos de código en períodos regulares de tiempo (aunque en la práctica el timer no es muy exacto). Estos períodos regulares se establecen con la propiedad interval.

Si por ejemplo colocas HorInicio = 08:00:00 y HorFinal = 08:15:00 el Beep sonará repetidamente hasta que la condición (Hora>=HorInicio And Hora<=HorFinal) sea False, es decir, durante 15 min.

Bueno espero que te sea de utilidad.
Suerte.


DiabloRojo

190
Visual Basic 6.0 e inferiores / Re: Uso Del Tipo Date
« en: Martes 14 de Septiembre de 2004, 15:02 »
Qué tal sirespi?
Interesante tu planteamiento. Me tomo la libertad de darte un par de ideas que tal vez podrían funcionar:
-Podrías almacenar las fechas en la que deseas que ocurran determinados eventos (o que se ejecute algún código) en una base de datos. Así por ejemplo, podrías tener en tu tabla los campos Fecha, HoraInicio y HoraFinal -podría haber alguno como TipoEvento y/o Descripción, depende de lo que desees hacer-.
-Luego en el evento Load de tu aplicación podrías consultar dicha tabla y comparar las fechas con la fecha actual, de ser iguales "bajarías" la información de los campos HoraInicio y HoraFinal -y cualquier otro campo- a determinadas variables. Incluso podrías introducirlas en una colección, por aquello de si tienes más de una "programación" para el mismo día.
-Finalmente, puedes hacer lo que te indica ebolo en su post. Algo así como:
Código: Text
  1.  
  2. If now&#62;=HoraInicial and now&#60;=HoraFinal Then
  3.    Beep
  4. End If
  5.  
  6.  

Bueno sirespi, sólo son unas ideas. Espero te sean de alguna utilidad.
Suerte.


DiabloRojo

191
Visual Basic 6.0 e inferiores / Re: Error De Tipos
« en: Viernes 10 de Septiembre de 2004, 21:03 »
Tienes toda la razón Juanolo. Todo comentario y sugerencia es bien recibido.
Gracias por tomarte el tiempo.

DiabloRojo

192
VB .NET / Re: Procedimiento En Un Modulo
« en: Viernes 10 de Septiembre de 2004, 20:22 »
Qué tal harol?
Si lo que deseas es llamar al procedimiento desde cada ventana lo que puedes hacer es pasar el nombre del form como parámetro al procedimiento. Te coloco un ejemplo hecho en VB6.0 y tu te encargas de modificarlo según te convenga:

El procedimiento:

Código: Text
  1.  
  2. Public Sub AgregarControl(FormNombre As String)
  3.    Dim i As Integer 'contador
  4.    Dim MiControl As CommandButton ' Tipo de control
  5.    
  6.    For i = 0 To VB.Forms.Count - 1 'Busca en cada elemento de la colección Forms
  7.       If (VB.Forms(i).Name = FormNombre) Then 'Indica a qué form se agrega el control
  8.          Set MiControl = VB.Forms(i).Controls.Add(&#34;VB.CommandButton&#34;, &#34;Command2&#34;)
  9.          MiControl.Caption = &#34;Agregado&#34;
  10.          MiControl.Visible = True
  11.       End If
  12.    Next i
  13. End Sub
  14.  
  15.  


Llamada al procedimiento (esto se hace desde cada ventana):

Código: Text
  1.  
  2. Private Sub Command1_Click()
  3.    AgregarControl Me.Name 'Llama al procedimiento y le pasa como parámetro el nombre del form que realiza la llamada
  4. End Sub
  5.  
  6.  

Espero que te ayude.
Suerte.

DiabloRojo

193
VB .NET / Re: Procedimiento En Un Modulo
« en: Viernes 10 de Septiembre de 2004, 02:27 »
Qué tal harol?
Coméntame cómo llamas o deseas llamar al procedimiento. Lo llamas desde cada form? o lo llamas desde un form específico y quieres que te agregue los controles a los demás?


DiabloRojo

194
Visual Basic 6.0 e inferiores / Re: Error De Tipos
« en: Viernes 10 de Septiembre de 2004, 02:20 »
Hola Kev.
Te agradezco la recomendación de validar las entradas. Como solo estoy practicando y soy el único que utilizará la aplicación no consideré necesario incluir validaciones. Lo que sí me extraña es que me esté me guardando con el formato mm/dd/yyyy siendo que mi computador está configurado al español. Por cierto, hay alguna forma de que aparezca en mi MSHFlexGrid el campo con el formato dd/mm/yyyy aunque en la tabla esté almacenado como mm/dd/yyyy?.

Bueno, muchas gracias por los comentarios y consejos.


DiabloRojo

195
Visual Basic 6.0 e inferiores / Re: Error De Tipos
« en: Jueves 9 de Septiembre de 2004, 21:02 »
Qué tal cpmario?
Gracias por contestar. Ya resolví el problema y venía a contestar cuando ví tu respuesta. La solución es la siguiente:

Código: Text
  1.  
  2.    Dim inicial As String
  3.    Dim final As String
  4.  
  5.    inicial= &#34;#&#34; & txtFechaInicial.Text & &#34;#&#34;
  6.    final= &#34;#&#34; & txtFechafinal & &#34;#&#34;
  7.  
  8.    cmdCriterio.CommandText=&#34;SELECT cedula,nombre,fechaNac FROM tabla1    WHERE fechaNac&#62; &#34; & inicial & &#34; And fechaNac &#60; &#34; & final
  9.  
  10.  

Según entiendo, las variables "inicial" y "final" NO tienen que ser de tipo Date ya que la propiedad CommandText es precisamente una cadena de caracteres (esto explica el error de tipos). Luego cuando se abre el recorset (con Open) ADO se encarga de convertir lo que contenga esta cadena -si es el caso- en una instruccuón SQL.

Bueno, eso era todo. Gracias a todos los que respondieron y a los que se tomaron el tiempo de leer mi duda.

Suerte.


DiabloRojo

196
Visual Basic 6.0 e inferiores / Re: Error De Tipos
« en: Jueves 9 de Septiembre de 2004, 02:15 »
Qué tal Kev?
Gracias por responder. Hago lo que me dices y me sigue mostrando el mismo error. Incluso he añadido la función CDate() a las líneas:

Código: Text
  1.  
  2.    inicial=CDate(txtFechaInicial.text)
  3.    final=CDate(txtFechaFinal.text)
  4.  
  5.  

Y me muestra el mismo error.

Añadí un control ADODC y un MSHFlexGrid para ver todos los registros y me doy cuenta que a pesar de haber colocado el campo fechanac de tipo fecha/hora en formato dd/mm/yyyy (fecha corta) los registros aparecen con el formato mm/dd/yyyy ¿tendrá esto que ver con la aparición del error?.

Agradezco toda ayuda.

DiabloRojo

197
VB .NET / Re: Procedimiento En Un Modulo
« en: Miércoles 8 de Septiembre de 2004, 23:21 »
Qué tal harol?
Si tu form se llama FrmAbout creo deberías usar:
Código: Text
  1.  
  2. FrmAbout.controls.add()
  3.  
  4.  

Cuando usas:
Código: Text
  1.  
  2. Dim Frm as New FrmAbout
  3.  
  4.  

lo que haces es crear una nueva instancia de tu formulario FrmAbout.

Suerte.

198
Visual Basic 6.0 e inferiores / Error De Tipos
« en: Miércoles 8 de Septiembre de 2004, 18:07 »
Qué tal amigos del foro?
Soy novatillo en la programación de bases de datos y ADO así que para practicar un poco decidí crearme, en access, una base de datos super simple de una sola tabla. Dicha tabla contiene 3 campos: cedula,nombre y fechanac cuyos tipos son texto, texto y fecha/hora respectivamente. El campo fechanac tiene un formato fecha corta del tipo 19/06/1994.
Para trabajar sobre la base de datos uso una referencia a ADO 2.0 y utilizo los tres objetos disponibles, es decir, un objeto conexion, un objeto command y un objeto recorset.
Ahora bien lo que deseo hacer es que el usuario pueda colocar dos fechas y que se devuelva en el recorset todas las fechas que estén dentro de dicho intervalo. Uso un código similar a este:

Código: Text
  1.  
  2. 'En la parte de declaracione generales
  3. Dim cnnMiCon As ADODB.Connection
  4. Dim cmdCriterio As ADODB.Command
  5. Dim rstTabla As ADODB.Recordset
  6. '
  7. '
  8. '
  9. 'En el botón de búsqueda
  10. Private Sub Buscar()
  11.    Dim inicial As Date
  12.    Dim final As Date
  13.    '
  14.    If txtFechaInicial.Text &#60;&#62; &#34;&#34; And txtFechaFinal.Text &#60;&#62; &#34;&#34; Then
  15.       '
  16.       Set rstTabla = Nothing
  17.       Set cmdCriterio = Nothing
  18.       Set cnnMiCon = Nothing
  19.       '
  20.       inicial = txtFechaInicial.Text
  21.       final = txtFechaFinal.Text
  22.       '
  23.       Set cnnMiCon = New ADODB.Connection
  24.       Set cmdCriterio = New ADODB.Command
  25.       Set rstTabla = New ADODB.Recordset  
  26.       '
  27.       cnnMiCon.ConnectionString = &#34;Provider=Microsoft.Jet.OLEDB.3.51;Persist Security                  Info=False;Data Source=C:&#092;WINDOWS&#092;Escritorio&#092;ProyectoFechas&#092;fechas97_1.mdb&#34;
  28.       cnnMiCon.Open
  29.       '
  30.       cmdCriterio.CommandText = &#34;SELECT cedula,nombre,fechaNac FROM tabla1 WHERE fechaNac&#62;'&#34; &         inicial & &#34;'&#34; And fechaNac &#60; &#34;'&#34; & final & &#34;'&#34;
  31.       '  
  32.       rstTabla.Open cmdCriterio.CommandText, cnnMiCon, adOpenDynamic
  33.       '
  34.       rstTabla.MoveFirst
  35.       txtCedula = rstTabla.Fields(&#34;cedula&#34;).Value
  36.       txtNombre = rstTabla.Fields(&#34;nombre&#34;).Value
  37.       txtFecha = rstTabla.Fields(&#34;fechaNac&#34;).Value
  38.    End If
  39. End Sub
  40.  
  41.  

Ahora bien, cuando corro el programa introduzco las fechas y pulso el botón buscar obtengo el error 13 "No coinciden los tipos" en la línea:

Código: Text
  1.  
  2.    cmdCriterio.CommandText = &#34;SELECT cedula,nombre,fechaNac FROM tabla1 WHERE fechaNac&#62;'&#34; &       inicial & &#34;'&#34; And fechaNac &#60; &#34;'&#34; & final & &#34;'&#34;
  3.  
  4.  

Si coloco directamente en el código por ejemplo:

Código: Text
  1.  
  2.    cmdCriterio.CommandText = &#34;SELECT cedula,nombre,fechaNac FROM tabla1 WHERE fechaNac &#62;            #1/1/1960# AND fechaNac &#60; #1/1/1991#&#34;
  3.  
  4.  
   
No obtengo ningún error.

Necesito dos cosas:
 1.- Estoy implementando bien el código para trabajar con ADO?
 2.- Cómo corrijo el error de tipos?

De antemano muchas gracias por la ayuda.

DiabloRojo

199
Visual Basic 6.0 e inferiores / Re: Transmitir Puerto Serie Modo Binario
« en: Viernes 27 de Agosto de 2004, 16:58 »
Qué tal sirespi?
Creo que el error está en la forma en que asignas cada elemento de la variable bin a la matríz. Tu colocas:

Código: Text
  1.  
  2. For x = 1 To 5 Step 1
  3.    var(x - 1) = Mid(bin, x, 1)
  4. Next x
  5.  
  6.  

Si por ejemplo bin="11" (3 en decimal) tendrías como resultado:

1 1 0 0 0   (24 en decimal)

que es muy distinto en binario a esto:

0 0 0 1 1   (3 en decimal)


Aquí te envío un ejemplo basado en tu código:

Código: Text
  1.  
  2.  
  3.  
  4. Private Sub Form_Load()
  5.    Dim var(15) As Integer
  6.    Dim x As Integer
  7.    Dim Valor As Long
  8.    Dim bin As String
  9.    Dim potencia
  10.    Dim Agregado As String
  11.  
  12. bin = &#34;11111&#34;
  13. 'bin = &#34;11&#34;
  14. 'bin = &#34;110&#34;
  15. 'bin = &#34;11110000111001&#34;
  16. 'bin = &#34;1000000000000000&#34;
  17.  
  18. Agregado = AgregarCero(bin)
  19.  
  20. For x = 16 To 1 Step -1
  21.    var(x - 1) = Val(Mid(Agregado, x, 1)) 'Notar el uso de la función val
  22. Next x
  23.  
  24. Valor = 0
  25. 'For x = 16 To 1 Step -1
  26. For x = 1 To 16 ' es lo mismo que lo anterior
  27.    Valor = Valor + (var(x - 1) * (2 ^ (16 - x)))
  28. Next x
  29. Text1.Text = Valor
  30.  
  31. End Sub
  32.  
  33.  
  34. Private Function AgregarCero(NumBin As String) As String
  35.    Dim longitud As Integer
  36.    Dim ParteNueva As String
  37.    Dim NuevoNum As String
  38.    Dim k As Integer
  39.   
  40.    longitud = Len(NumBin)
  41.   
  42.    For k = 1 To 16 - longitud
  43.       ParteNueva = ParteNueva & &#34;0&#34;
  44.    Next k
  45.       NuevoNum = ParteNueva + NumBin
  46.       AgregarCero = NuevoNum
  47. End Function
  48.  
  49.  
  50.  
  51.  

Bueno, espero que esto te resulte de utilidad. Revísalo y luego me dices.
Suerte.

200
Visual Basic 6.0 e inferiores / Re: Uso De Control
« en: Miércoles 25 de Agosto de 2004, 01:55 »
Hola.
El control del cual hablas se llama TabStrip y para poder utilizarlo debes agregar el Microsoft Windows Common Controls 6.0 ó 5.0. Sobre cómo utilizarlo yo tampoco tengo idea jeje. Espero haberte ayudado en algo.

Suerte.

Páginas: 1 ... 6 7 [8] 9