I have a query that that connects to several remote machines to union data into a single table. It works fine when all the machines are connected but occasionally any given machine may be turned off (which results in error), I'd like my query to ignore any connections that are unavailable and continue with the rest of the query. Is there any way to do this?
I'm using linked tables with an OBDC conncetion (driver: MySql ODBC 5.3 Ansi Driver)
Here is my query:
SELECT "HX32" AS workcenter, "HX32." & [HX32].[dataid] AS tbldataid, HX32.dataid AS dataid, HX32.TS, DMin("[TS]","[HX32]","[TS] > #" & [TS] & "#") AS EndTS, DateDiff("s",[TS],EndTS) AS durationsec, Format(Int([durationsec]/86400)) & " " & Format([durationsec]/86400,"hh:nn:ss") AS duration, Format(TS,"mm/dd/yyyy") AS [Day], Switch(incycle=0,'Down',incycle=1,'Running') AS Status
FROM HX32
WHERE (((HX32.TS)>Date()-3) AND ((HX32.incycle)=0))
UNION ALL
SELECT "VL65A" AS workcenter, "VL65A." & [VL65A].[dataid] AS tbldataid, VL65A.dataid AS dataid, VL65A.TS, DMin("[TS]","[VL65A]","[TS] > #" & [TS] & "#") AS EndTS, DateDiff("s",[TS],EndTS) AS durationsec, Format(Int([durationsec]/86400)) & " " & Format([durationsec]/86400,"hh:nn:ss") AS duration, Format(TS,"mm/dd/yyyy") AS [Day], Switch(incycle=0,'Down',incycle=1,'Running') AS Status
FROM VL65A
WHERE (((VL65A.TS)>Date()-3) AND ((VL65A.incycle)=0))
UNION ALL
SELECT "VL68B" AS workcenter, "VL68B." & [VL68B].[dataid] AS tbldataid, VL68B.dataid AS dataid, VL68B.TS, DMin("[TS]","[VL68B]","[TS] > #" & [TS] & "#") AS EndTS, DateDiff("s",[TS],EndTS) AS durationsec, Format(Int([durationsec]/86400)) & " " & Format([durationsec]/86400,"hh:nn:ss") AS duration, Format(TS,"mm/dd/yyyy") AS [Day], Switch(incycle=0,'Down',incycle=1,'Running') AS Status
FROM VL68B
WHERE (((VL68B.TS)>Date()-3) AND ((VL68B.incycle)=0))
;
I ended up using VBA to solve per #Erik's comments:
It loops through each connection checks it, if connection is good it modifies a query and runs.
Dim cnn As ADODB.Connection
Dim canConnect As Boolean
Set cnn = New ADODB.Connection
Dim conctns As Variant
Dim conctn As Variant
conctns = Array("HX32", "VL65A", "VL68B")
For Each conctn In conctns
On Error GoTo sub_error
cnn.Open conctn
If cnn.State = adStateOpen Then
canConnect = True
strSQL = "SELECT '" & conctn & "' AS workcenter, '" & conctn & ".' & [" & conctn & "].[dataid] AS tbldataid, " & conctn & ".dataid AS dataid, " & conctn & ".TS, DMin('[TS]','[" & conctn & "]','[TS] > #' & [TS] & '#') AS EndTS, DateDiff('s',[TS],EndTS) AS durationsec, Format(Int([durationsec]/86400)) & ' ' & Format([durationsec]/86400,'hh:nn:ss') AS duration, Format(TS,'mm/dd/yyyy') AS [Day], Switch(incycle=0,'Down',incycle=1,'Running') AS Status FROM " & conctn & " WHERE (((" & conctn & ".TS)>Date()-3) AND ((" & conctn & ".incycle)=0));"
CurrentDb.QueryDefs("unionall").SQL = strSQL
DoCmd.OpenQuery "appendall", acViewNormal, acEdit
DoCmd.OpenQuery "splithours", acViewNormal, acEdit
MsgBox conctn & " updated: " & canConnect
cnn.Close
End If
sub_error:
MsgBox conctn & ": " & Error$
Resume sub_error_exit
sub_error_exit:
Next conctn
Related
Teller = Nz(DLookup("[Teller]", "[Lookuptable]", ("Artikel = '" & ValueArtikel & "' " And " Lookuptable= 'G'")), 0)
Noemer = Nz(DLookup("[Noemer]", "[lookuptable]", ("Artikel = ' " & ValueArtikel & " ' " And Lookuptable= " 'G' ")), 0)
I want to perform a DLOOKUP in acces vba but i can't find the right statement. I looked at many sites and this are the two dlookups that i think are correct but both give the error types don't match. Teller and noemer are integers, Artikel and artikelvalue and Lookuptable are strings. Sorry if this is already asked but i can't find it. i find many posts about it but i can't fixed it. And especcialy sorry for my bad english
The first one is close. Use variables and Debug.Print to help building the strings.
Ctrl+g shows the output.
strCrit = "Artikel = '" & ValueArtikel & "' And Lookuptable= 'G'"
Debug.Print strCrit
Teller = Nz(DLookup("[Teller]", "[Lookuptable]", strCrit), 0)
I use my own function for Lookups because Lookups have a really bad performance.
' Lookups Replacements
'---------------------
Function DLook(Expression As String, Domain As String, Optional Criteria) As Variant
On Error GoTo Err_Handler
Dim strSQL As String
'DCount: strSQL = "SELECT COUNT(" & Expression & ") FROM " & Domain
'Other replacements
'DLookup:
strSQL = "SELECT " & Expression & " FROM " & Domain
'DMax: strSQL = "SELECT MAX(" & Expression & ") FROM " & Domain
'DMin: strSQL = "SELECT SUM(" & Expression & ") FROM " & Domain
'DFirst: strSQL = "SELECT FIRST(" & Expression & ") FROM " & Domain
'DLast: strSQL = "SELECT LAST(" & Expression & ") FROM " & Domain
'DSum: strSQL = "SELECT SUM(" & Expression & ") FROM " & Domain
'DAvg: strSQL = "SELECT AVG(" & Expression & ") FROM " & Domain
If Not IsMissing(Criteria) Then strSQL = strSQL & " WHERE " & Criteria
DLook = DBEngine(0)(0).OpenRecordset(strSQL, dbOpenForwardOnly)(0)
Exit Function
Err_Handler:
MsgBox "Error. Lookup couldnt be performed" & vbNewLine & Err.Description, vbCritical
End Function
Called with:
If DLook("Column2", "Table1", "Column1 = " & ID) = 0 Then
'Do stuff
End If
If DLook("Column2", "Table1") = 0 Then
'Do other stuff
End If
I am trying to create a Form that is used to manually enter data in certain scenarios. Most data is input from CSV files which is working fine. I have 4 tables, Part , Assembly , MachineOrder , and Job. I was able to write code for entering into the base table, Part, from the Form no problem. The issue now is entering data into the Assembly and MachineOrder tables where the Parts are being referenced by their PID autonumber field and the Assemblies are being referenced by their AID autonumbered field. I have tried many different kinds of methods to perform this of which you can see a bit of in my commented out code. What is there is what I believe to be my closest to correct code thus far with the error now being that Access asks me for the parameter value of rPID even though it is finding the value in the Dlookup function fine. I'm assuming the same is true for the rAID section as well.
Otherwise I'm getting errors of Key Violations when using the INSERT then UPDATE method you see commented out.
The form is called HOTEntry
Any advice on what my problem may be is greatly appreciated, I'm a student and this is my first time trying to use what I've learned in a professional application so any and all constructive criticism is wanted! Apologies if this is a rather specific question but I could really use the help on this since I've been working on it for two days to no avail...
My code:
Sub HOTParts2()
Dim rPID As Integer
Dim rAID As Integer
Dim dbs As DAO.Database
Dim sqlstr1 As String
Dim sqlstr2 As String
Dim sqlstr3 As String
Dim sqlstr4 As String
Set dbs = CurrentDb
'sqlstr1 = "INSERT INTO Assembly ( PID, ModelNum, ModelRev, ModelDescription ) " _
' & "SELECT (PID,Forms!HOTEntry!txtHotModel, Forms!HOTEntry!txtHotRev, Forms!HOTEntry!txtHotDes)" _
' & "FROM Part " _
' & "WHERE Part.PartName = Forms!HOTEntry!txtPartName AND Part.Config = Forms!HOTEntry!txtConfigEntry AND Part.Rev = Forms!HOTEntry!txtRevEntry"
sqlstr1 = "INSERT INTO Assembly ( ModelNum, ModelRev, ModelDescription,PID ) " _
& "VALUES (Forms!HOTEntry!txtHotModel, Forms!HOTEntry!txtHotRev, Forms!HOTEntry!txtHotDes," & "rPID" & ");"
'
'sqlstr2 = "UPDATE Assembly " _
' & "SET PID =" & rPID & " " _
' & "WHERE Assembly.ModelNum = Forms!HOTEntry!txtHotModel And Assembly.ModelDescription = Forms!HOTEntry!txtHotDes And Assembly.ModelRev = Forms!HOTEntry!txtHotRev;"
'
'sqlstr3 = "INSERT INTO MachineOrder ( AID, Serial, CustName ) " _
' & "SELECT (AID,Forms!HOTEntry!txtHotSerial, Forms!HOTEntry!txtHotCust)" _
' & "FROM Assembly" _
' & "WHERE Assembly.Model=Forms!HOTEntry!txtHotModel And ModelDescription= Forms!HOTEntry!txtHotDes And ModelRev = Forms!HOTEntry!txtHotRev; "
sqlstr3 = "INSERT INTO MachineOrder (Serial, CustName, AID ) " _
& "VALUES (Forms!HOTEntry!txtHotSerial, Forms!HOTEntry!txtHotCust," & "rAID" & ");"
'
'sqlstr4 = "UPDATE MachineOrder " _
' & "SET AID =" & rAID & " " _
' & "WHERE AID IS NULL;"
rPID = DLookup("PID", "Part", "PartName = " & "'" & Forms!HOTEntry!txtPartName & "'" & " And " & "Config = " & "'" & Forms!HOTEntry!txtConfigEntry & "'" & " And " & "Rev = " & "'" & Forms!HOTEntry!txtRevEntry & "'")
DoCmd.RunSQL sqlstr1
'DoCmd.RunSQL sqlstr2
rAID = DLookup("AID", "Assembly", "ModelNum = " & "'" & Forms!HOTEntry!txtHotModel & "'" & " And " & "ModelDescription = " & "'" & Forms!HOTEntry!txtHotDes & "'" & " And " & "ModelRev = " & "'" & Forms!HOTEntry!txtHotRev & "'")
DoCmd.RunSQL sqlstr3
'DoCmd.RunSQL sqlstr4
End Sub
Well, if you want to use the looked up rPID and rAID in a query, you need to do more than just set them in VBA. You can either manually fill them in in your SQL statement, use a parameter and a QueryDef and fill in the parameter in your QueryDef, or put the DLookUp inside your SQL statement.
Going with the first approach here, only unquoted rPID in your initial statement, and put it after rPID was set.:
rPID = DLookup("PID", "Part", "PartName = " & "'" & Forms!HOTEntry!txtPartName & "'" & " And " & "Config = " & "'" & Forms!HOTEntry!txtConfigEntry & "'" & " And " & "Rev = " & "'" & Forms!HOTEntry!txtRevEntry & "'")
sqlstr1 = "INSERT INTO Assembly ( ModelNum, ModelRev, ModelDescription,PID ) " _
& "VALUES (Forms!HOTEntry!txtHotModel, Forms!HOTEntry!txtHotRev, Forms!HOTEntry!txtHotDes," & rPID & ");"
DoCmd.RunSQL sqlstr1
I need to verify the operations done in an account at a particular period of time by asking the user to enter account number and the date range, but each time I run it I have the error "type mismatch"
Here is the code:
Private Sub cmdSearch_Click()
Call search
End Sub
Sub search()
Dim strCriteria, strCount, task As String
Me.Refresh
If IsNull(Me.compte_hist) Or IsNull(Me.date_deb) Or IsNull(Me.date_fin) Then
MsgBox "s'il vous plaƮt assurez-vous que tous les champs sont remplis", vbInformation, "Date Range Required"
Me.compte_hist.SetFocus
Else
strCriteria = "([Date_operation]>= #" & Me.date_deb & "# And [Date_operation] <= #" & Me.date_fin & "#)"
strCount = "[Compte]=#" & Me.compte_hist & "#"
task = "select * from Operations where Operations (" & strCriteria & ")" And " (" & strCount & ") order by [Date_operation]"
DoCmd.ApplyFilter task
End If
End Sub
Try this:
strCriteria = "([Date_operation]>= #" & Format(Me.date_deb, "mm\/dd\/yyyy") & "# And [Date_operation] <= #" & Format(Me.date_fin, "mm\/dd\/yyyy") & "#)"
strCount = "[Compte]=" & Me.compte_hist
task = "select * from Operations where (" & strCriteria & ") And (" & strCount & ") order by [Date_operation]"
Me.RecordSource = task
Also you can apply filter only:
strCriteria = "([Date_operation]>= #" & Format(Me.date_deb, "mm\/dd\/yyyy") & "# And [Date_operation] <= #" & Format(Me.date_fin, "mm\/dd\/yyyy") & "#)"
strCount = "[Compte]=" & Me.compte_hist
task = "(" & strCriteria & ") And (" & strCount & ")"
Me.Filter = task
Me.FilterOn = True
If account number is not numeric, use quotes:
strCount = "[Compte]='" & Me.compte_hist & "'"
I have the following function running on form load when the database opens. I know something is missing but I am not sure what exactly. The code runs fine until it opens a form so the user can select a printer. Then the form has it's own that it works through.
I put a break in and the code stops on the SelectPrinter sub so I guess I need that code to return to the function or can I write the code into the function?
This is the function:
Option Compare Database
Function PrintReports()
Dim ExeCount As Long
Dim ExdCount As Long
Dim ExiCount As Long
Dim ExnCount As Long
Dim ExpCount As Long
Dim Answer As Integer
DoCmd.SetWarnings (WarningsOff)
'Create Ex e Table
DoCmd.RunSQL "SELECT tbl_AHAD.*, IIf([Last_Insp_Date] Is Null,Date(),DateAdd('yyyy',4,[Last_Insp_Date]))
AS Due_Date " & _
"INTO tbl_Ex_e " & _
"FROM tbl_AHAD " & _
"WHERE (((IIf([Last_Insp_Date] Is Null,Date(),DateAdd('yyyy',4,
[Last_Insp_Date])))<=Date()) " & _
"AND ((tbl_AHAD.Device_Class) In ('Ex e','Ex eb','Ex ed','Ex em','Ex
emb','Ex mb','Ex mbe','Ex me')))" & _
"ORDER BY tbl_AHAD.Maint_Item"
'Create Ex d Table
DoCmd.RunSQL "SELECT tbl_AHAD.*, IIf([Last_Insp_Date] Is
Null,Date(),DateAdd('yyyy',4,[Last_Insp_Date])) AS Due_Date " & _
"INTO tbl_Ex_d " & _
"FROM tbl_AHAD " & _
"WHERE (((IIf([Last_Insp_Date] Is Null,Date(),DateAdd('yyyy',4,
[Last_Insp_Date])))<=Date()) " & _
"AND ((tbl_AHAD.Device_Class) In ('Class 1','Ex d','Ex de','Ex dmb')))" & _
"ORDER BY tbl_AHAD.Maint_Item"
'Create Ex i Table
DoCmd.RunSQL "SELECT tbl_AHAD.*, IIf([Last_Insp_Date] Is
Null,Date(),DateAdd('yyyy',4,[Last_Insp_Date])) AS Due_Date " & _
"INTO tbl_Ex_i " & _
"FROM tbl_AHAD " & _
"WHERE (((IIf([Last_Insp_Date] Is Null,Date(),DateAdd('yyyy',4,
[Last_Insp_Date])))<=Date()) " & _
"AND ((tbl_AHAD.Device_Class) In ('Ex i','Ex ia')))" & _
"ORDER BY tbl_AHAD.Maint_Item"
'Create Ex n Table
DoCmd.RunSQL "SELECT tbl_AHAD.*, IIf([Last_Insp_Date] Is
Null,Date(),DateAdd('yyyy',4,[Last_Insp_Date])) AS Due_Date " & _
"INTO tbl_Ex_n " & _
"FROM tbl_AHAD " & _
"WHERE (((IIf([Last_Insp_Date] Is Null,Date(),DateAdd('yyyy',4,
[Last_Insp_Date])))<=Date()) " & _
"AND ((tbl_AHAD.Device_Class) In ('Ex n','Ex nA','Ex nR')))" & _
"ORDER BY tbl_AHAD.Maint_Item"
'Create Ex p Table
DoCmd.RunSQL "SELECT tbl_AHAD.*, IIf([Last_Insp_Date] Is
Null,Date(),DateAdd('yyyy',4,[Last_Insp_Date])) AS Due_Date " & _
"INTO tbl_Ex_p " & _
"FROM tbl_AHAD " & _
"WHERE (((IIf([Last_Insp_Date] Is Null,Date(),DateAdd('yyyy',4,
[Last_Insp_Date])))<=Date()) " & _
"AND ((tbl_AHAD.Device_Class) In ('Ex p'))) " & _
"ORDER BY tbl_AHAD.Maint_Item"
DoCmd.SetWarnings (WarningsOff)
'Open message box to ensure user wants to continue
ExeCount = DCount("ID", "tbl_Ex_e")
ExdCount = DCount("ID", "tbl_Ex_d")
ExiCount = DCount("ID", "tbl_Ex_i")
ExnCount = DCount("ID", "tbl_Ex_n")
ExpCount = DCount("ID", "tbl_Ex_p")
Answer = MsgBox("There are " & vbCrLf & vbCrLf & ExeCount & " Ex e Reports
" & vbCrLf & ExdCount & " Ex d Reports " & vbCrLf & _
ExiCount & " Ex i Reports" & vbCrLf & ExnCount & " Ex n Reports" &
vbCrLf & ExpCount & " Ex p Reports" & _
vbCrLf & vbCrLf & "Records to Print", vbOKCancel)
'If Ok then print all reports
If Answer = vbOK Then
DoCmd.OpenForm "SelectPrinter", , , , , acDialog
**'Stopping here**
Set Application.Printer = _
Application.Printers(cboDestination.ListIndex)
DoCmd.Close acForm, "SelectPrinter", acSaveYes
If ExpCount > 0 Then
DoCmd.OpenReport "rpt_Ex_p"
End If
' Switch back to original default printer
Set Application.Printer = Application.Printers(strDefaultPrinter)
Else
Exit Function
End If
'Update table with today's date
DoCmd.RunSQL "UPDATE tbl_AHAD INNER JOIN tbl_Ex_p ON tbl_AHAD.ID = tbl_Ex_p.ID " & _
"SET tbl_AHAD.Last_Insp_Date = Date() "
End Function
This is the sub that runs along with it's function after the DoCmd.OpenForm "SelectPrinter", , , , , acDialog
Private Sub Form_Load()
cboDestination = ""
m_GetPrinters cboDestination
cboDestination.SetFocus
cboDestination.ListIndex = 0
End Sub
Public Sub m_GetPrinters(ByRef objListOrCombo As Object)
Dim objPrinter As Printer
Dim intNbOfPrinters As Integer
intNbOfPrinters = Printers.Count - 1
For Each objPrinter In Printers
objListOrCombo.AddItem objPrinter.DeviceName
Next
End Sub
You specifically open the form in dialogue mode:
DoCmd.OpenForm "SelectPrinter", , , , , acDialog
Thus, your code will not stop, but it turns to the form opened and silently waits until that form is closed - then the code will proceed.
If you wish to open the form and have the function PrintReports() to continue without taking notice of the form, then don't use the acDialog setting.
When I run this code, I get "The Open Form action was canceled" with an error code of 2501 The line it gets caught on when I debug is the DoCmd.RunSQL (Req)
Function Compare()
Dim oDB As DAO.Database
Dim oRst As DAO.Recordset
Dim nbligne As Long
Dim Req As String
Dim default As String
Dim tables As String
Dim table
Dim i As Integer
Dim champ As String
Dim j As Integer
Set oDB = CurrentDb
Set oRst = oDB.OpenRecordset("SELECT Count(*) FROM CELLCAC;")
nbligne = oRst.Fields(0).Value
Set oRs = CurrentDb.OpenRecordset("CELLCAC")
Set fs = CreateObject("Scripting.FileSystemObject")
Set fldr = fs.getfolder("C:\Users\Documents\Application\Application_vba\Delta")
Set fls = fldr.files
Set fld = CurrentDb.OpenRecordset("TABLES_A_VERIFIER_DEFAULT")
For Each fl In fls
If fl Like "*.txt" Then
source = Left(fl.Name, Len(fl.Name) - 4)
tables = source
default = "DEFAULT_" & tables
table = CurrentDb.OpenRecordset(default)
For i = 0 To table.Count - 1
champ = table(i).Name
Req = "INSERT INTO DELTA_DEFAULT(BSCNAME, CELLNAME, MO, PARAMETRE ,DEFAULT ,RESEAU)" _
& "select DISTINCT [" & tables & "]![BSCNAME], [" & tables & "]![CELLNAME],('" & tables & "'), ('" & champ & "') ,[" & default & "]![" & champ & "],[" & tables & "]![" & champ & "] " _
& " from (" & tables & ") INNER join (" & default & ") on ( " & default & ".Zone = " & tables & ".Zone ) " _
& " Where [" & default & "]![" & champ & "] <> [" & tables & "]![" & champ & "];"
DoCmd.RunSQL (Req)
Next i
End If
Next fl
End Function
Instead of doing : DoCmd.RunSQL (Req),
can you try : oDB.Execute (Req)
I had several issues and this helps me a lot !
From the first line of your req query to the second line, you need to add a space character.
I believe that currently the query will not recognise the word SELECT if it is joined to the closed bracket.
Req = "INSERT INTO DELTA_DEFAULT(BSCNAME, CELLNAME, MO, PARAMETRE,DEFAULT ,RESEAU)" _
& " select
In addition; from what I understood I would have used the VALUES clause when creating an INSERT INTO statement. Perhaps:
Req = "INSERT INTO DELTA_DEFAULT(BSCNAME, CELLNAME, MO, PARAMETRE ,DEFAULT ,RESEAU)" _
& " VALUES (select DISTINCT [" & tables & "]![BSCNAME], [" & tables & "]![CELLNAME],('" & tables & "'), ('" & champ & "') ,[" & default & "]![" & champ & "],[" & tables & "]![" & champ & "] " _
& " from (" & tables & ") INNER join (" & default & ") on ( " & default & ".Zone = " & tables & ".Zone ) " _
& " Where [" & default & "]![" & champ & "] <> [" & tables & "]![" & champ & "]);"