problemas y dudas con ADO

Iniciado por Majinz, 7 Mayo 2011, 06:48 AM

0 Miembros y 1 Visitante están viendo este tema.

Majinz

Hola que tal como estan, nuevamente los molesto con una duda, estoy haciendo una aplicacion que mediante una db responde preguntas, el problema radica en que cuando quiero probar la aplicacion me tira este error "procedimiento externo no valido" en la segunda linea podria alguien decirme que hice mal, no se si esto influya en algo pero la db tiene una tabla llamada dialogo y dos columnas, la primera es pregunta y la segunda es respuesta
Código (vb) [Seleccionar]

Dim adoConexion As New ADODB.Connection
adoConexion.ConnectionString = "Provider = Microsoft.Jet.OLEDB.4.0; Persist Security Info=True; Data Source = (App.Path & \Dialogo.MDB)"
adoConexion.Open

Dim sSQLQuery As String
sSQLQuery = "SELECT *" & vbCr
sSQLQuery = sSQLQuery & "FROM Dialogo" & vbCr
sSQLQuery = sSQLQuery & "WHERE Nombre = '" & Text2.Text & "'" & vbCr

Dim adoRegistros As New ADODB.Recordset
adoRegistros.Open sConsulta, adoConexion, adOpenStatic, adLockReadOnly

Private Sub Command1_Click()
If adoRegistros.BOF = adoRegistros.EOF And adoRegistros.EOF = False Then
Label1.Text = adoConsulta!Respuesta
End If
End Sub

seba123neo

#1
Hola, te felicito por usar ADO y desde codigo, y no usar controles como el ADODC o DATA.

primero que nada decirte que no declares las variables como As New, y siempre lo hagas con As primero, y despues setearla con Set, ¿porque? bueno porque la primera forma esta desaconsejada usar por temas de performance, ya que el visual basic internamente chequea (cada vez que usas la variable), chequea si el objeto esta instanciado o no, en cambio de la segunda forma no lo hace y es la correcta, aparte una vez me paso de mantener un sistema que lanzaba un error y era porque estaba declarada una variable con As New, desde el IDE funcionaba correctamente, pero al compilarlo lanzaba error y era por eso.esto es para cualquier objeto.

siempre que se usa algo de bases de datos es bueno usar un modulo comun para declarar las variables globales y ahi en el Sub_Main del modulo hacer la conexion a al base, y dejar los formularios sin ese codigo.

para eso debes agregar un modulo y en las propiedades de tu proyecto, debes cambiar para que el proyecto comienze desde el Sub_Main y no desde el Formulario, eso lo cambias en una opcion llamada Objeto de Inicio.

estas 2 variables adoConexion y adoRegistros deben ir en un modulo comun.

y debes en el Sub_Main setearlas y conectarte a la base.

aca te paso un codigo de como deberia quedar el modulo.

Código (vb) [Seleccionar]
Option Explicit

Public mConexion As ADODB.Connection 'Conexion Principal
Public mRs As ADODB.Recordset  'Recordset Principal
Public mRsAux As ADODB.Recordset  'Recordset Auxiliar
Public mCmd As ADODB.Command 'Para Ejecutar Comandos

Sub Main()
   
   Set mConexion = New ADODB.Connection
   Set mRs = New ADODB.Recordset
   Set mRsAux = New ADODB.Recordset
   Set mCmd = New ADODB.Command
       
   mConexion.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "\TuBase.mdb;"
   mConexion.Open
   
   frmLogin.Show ' Aca mostras tu Formulario de inicio
   
End Sub


otra cosa, esa variable que puse llamada mCmd es para ejecutar comandos SQL, o sea INSERTS, DELETE, UPDATE a la base de datos, ya que yo opto por usarlo asi en vez de usar los metodos .AddNew o .Update o Delete del recordset, lo cual te va a enseñar de paso el lenguaje SQL.

ahi fijate el codigo App.Path & "\TuBase.mdb;", ahi cambiale el nombre por el de tu base y ese App.Path hace que la base de datos daba estar en la misma carpeta del proyecto donde va a estar el .exe compilado despues, ya que no debes usar rutas fijas como por ejemplo "C:\base\base.mdb" ya que eso solo funcionaria en tu pc, siempre la base debe estar en el directorio de la aplicacion o en una subcarpeta en este, o en una carpeta de red compartida. eso lo tenes mal ahi vos en el codigo por eso no te funciona.

no hace falta que pongas los vbCr en la cadena SQL.

saludos.
La característica extraordinaria de las leyes de la física es que se aplican en todos lados, sea que tú elijas o no creer en ellas. Lo bueno de las ciencias es que siempre tienen la verdad, quieras creerla o no.

Neil deGrasse Tyson

raul338

Cita de: Majinz en  7 Mayo 2011, 06:48 AM
Código (vb) [Seleccionar]

If adoRegistros.BOF = adoRegistros.EOF And adoRegistros.EOF = False Then
Label1.Text = adoConsulta!Respuesta
End If


No se si sea error tuyo (Text en lugar de caption) o es que me suena a .net

Majinz

muchas gracias seba123neo has sido muy amable y explicito, tenias razon, voy a poner en practica tus consejos, tengo otra duda tu variable mCmd hace innecesario las query verdad?
tienes razon raul338, es que en un principio eran dos txtbox, pero el que obtenia la respuesta era innecesario, y lo cambie por un label, a la vista queda mas lindo :)

Majinz

#4
seba123neo use tu modulo y arregle mi form quedo asi

Código (vb) [Seleccionar]
Private Sub Command1_Click()
If mRs.BOF = mRs.EOF And mRs.EOF = False Then
Label1.Caption = adoConsulta!Respuesta
End If
End Sub

Private Sub Form_Unload(Cancel As Integer)
mConexion.Close
Set mConexion = Nothing
End
End Sub


pero me tira este error "la operacion no esta permitida si el objeto esta cerrado"

intente esto

Código (vb) [Seleccionar]
Private Sub Command1_Click()
mConexion.Open
If mRs.BOF = mRs.EOF And mRs.EOF = False Then
Label1.Caption = adoConsulta!Respuesta
End If
End Sub

Private Sub Form_Unload(Cancel As Integer)
mConexion.Close
Set mConexion = Nothing
End
End Sub


Ahora el error es inverso, es decir "la operacion no esta permitida si el objeto esta abiero", si no es molestia podrias decirme a que se debe?

seba123neo

Majinz, cuando publiques codigo trata de ponerlo entre el geshi de visual basic, por las dudas es [ code=vb] tu codigo aca... [ /code] asi queda mejor, y trata de indentar el codigo fuente.

el modulo que yo te puse lo unico que hace es crear e instanciar las variables publicas para usarlas en el proyecto cuando quieras, y conectarte a la base de datos, eso es lo que hace el modulo.

la variable mCmd es para ejecutar comandos, o sea cuando necesites insertar registros , actualizar registros o borrar registros vas a usar esta variable.

por ahora lo que vos necesitas es hacer una consulta(SELECT) a la base, pero para eso debes usar la variable mRs y para que funcione debes pasarle la consulta SQL que necesitas hacer. eso no lo veo en tu codigo por eso te tira error, en ningun momento veo que abras el recordset para hacer la consulta. tampoco necesitas hacer ese mConexion.Open, ya que la conexion a la base ya esta abierta desde el modulo, y queda abierta y activa todo el programa, hasta que se cierra.

aca te paso un ejemplo de como lo haria yo, una simple consulta a la base de datos, supongamos que estas usando el modulo que te pase, esto deberia funcionar.

Código (vb) [Seleccionar]
Option Explicit

Private Sub Command1_Click()
    Call CargarDatos
End Sub

Private Sub CargarDatos()
    Dim vSQL As String
   
    vSQL = "SELECT campo FROM tabla" ' String para la consulta SQL
    mRs.Open vSQL, mConexion, adOpenKeyset, adLockOptimistic, adCmdText ' abris el recodset publico con la consulta
   
    If mRs.EOF Then ' Si tiene datos
        Label1.Caption = mRs("campo") ' obtenemos el valor del campo de la consulta
    End If
   
    mRs.Close 'cerramos el recordset para que quede disponible para usar de nuevo cuando queramos.
End Sub

Private Sub Form_Unload(Cancel As Integer)
    mConexion.Close
    Set mConexion = Nothing
    End
End Sub


fijate que simple que es, simplemente en el boton llamamos a un Sub que nos hace la consulta. ahi esta explicado en el codigo lo que hace cada linea.

si por alguna razon alguna vez necesitas de usar 2 recorset al mismo tiempo, fijate que en el modulo hay otro auxiliar para llamarlo cuando quieras, y si por las dudas necesitas un tercero o mas...los declaras en el formulario como local, lo usas y los cerras ahi mismo.

saludos.
La característica extraordinaria de las leyes de la física es que se aplican en todos lados, sea que tú elijas o no creer en ellas. Lo bueno de las ciencias es que siempre tienen la verdad, quieras creerla o no.

Neil deGrasse Tyson