visual programar ejemplos codigos vba access-vba ms-access-2002

programar - Desde la forma principal, ejecute VBA para validar total en subformulario



vba access pdf (2)

Me saltaría usar la interfaz de usuario por completo y mirar las tablas. Si esto se ejecuta en un botón de comando de formulario principal, el subformulario ha perdido el foco y ha guardado sus valores. Una nueva consulta es innecesaria. Simplemente recree la relación Padre-Hijo en el criterio (tercer parámetro) de un DSum:

If DSum("QtyToShip", "ShipmentDetails", "ShipmentID = " & Me!ShipmentID) <= 0 Then MsgBox "Cannot create shipment, no quantities have been entered", vbCritical Exit Sub End If

Tengo un formulario en MS Access 2002 con el siguiente fragmento de código detrás de un botón de comando.

''Requery subform to make sure total is calculated Me.fsubUpdateShipments.Requery DoEvents ''Confirm quantities have been entered If Form_fsubUpdateShipments.txtTotalShipmentQty.Value <= 0 Then MsgBox "Cannot create shipment, no quantities have been entered", vbCritical Exit Sub End If

Durante meses, esto ha funcionado bien, pero hoy un colega vino a mí y me explicó que el mensaje de error aparecía incluso cuando habían ingresado cantidades.

Después de investigar un poco, determiné que la .Value <= 0 estaba siendo evaluada antes de que el cuadro de texto en cuestión terminara de calcular su valor: =Sum([QtyToShip]) . Esto parece ocurrir solo cuando el subformulario tiene una cantidad no trivial de registros (alrededor de 10 o más) y obviamente es un problema grave.

Agregar un punto de interrupción en la línea que contiene la instrucción If permite que el código se ejecute correctamente, pero obviamente no puedo usar este método permanentemente.

¿Hay alguna manera de forzar al código a pausar hasta que los controles del subformulario hayan terminado de recalcular sus valores?


Hay dos opciones, ambas ya identificadas por otros, pero como sus sugerencias son incompletas o desordenadas (lentas), estoy haciendo esta publicación.

R. Podría poner una espera forzada para retrasar la prueba IF:

Pon esto en un módulo:

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) ... Public Sub GoSleep(millisecondDelay as long) Sleep (millisecondDelay) End Sub

Y en tu forma:

''Requery subform to make sure total is calculated Me.fsubUpdateShipments.Requery DoEvents GoSleep 1000 ''1 second delay. Or 2000, whatever is required really ''Confirm quantities have been entered If Form_fsubUpdateShipments.txtTotalShipmentQty.Value <= 0 Then MsgBox "Cannot create shipment, no quantities have been entered", vbCritical Exit Sub End If

B. Como dice otra respuesta, puede recalcularlo usted mismo y evaluarlo en función de este resultado.

Sin embargo, en lugar de usar DSum como sugiere pteranodon, sugeriría algo más rápido que DSum, ya que DSum (DCount, etc.) es muy lento.

Normalmente utilizo ADO para operaciones de datos, aunque mi código se puede adaptar para DAO con la suficiente rapidez. Para usar este código necesitarás una referencia a Microsoft activeX 2.8 si aún no tienes uno:

En un módulo:

Public Function GetDBValue(qry as string) as variant dim rst as new adodb.recordset rst.open qry, currentproject.connection, adOpenKeyset, adLockReadOnly if rst.eof then GetValue = null else GetValue = rst.fields(0) end if end function public Function IsNullSQL(basevalue as variant, replacementvalue as variant) as variant isNullSQL = iif(isnull(basevalue), replacementvalue, basevalue) end function

en tu forma:

''''Requery subform to make sure total is calculated ''Me.fsubUpdateShipments.Requery ''DoEvents ''Confirm quantities have been entered If IsNullSQL(GetValue("SELECT Sum(QtyToShip) FROM tbl WHERE ..."), -1) < 0 Then MsgBox "Cannot create shipment, no quantities have been entered.", vbCritical, "No Quantities to Ship" Exit Sub End If ''If Form_fsubUpdateShipments.txtTotalShipmentQty.Value <= 0 Then '' MsgBox "Cannot create shipment, no quantities have been entered", vbCritical '' Exit Sub ''End If