Here's my problem:
Let's say I have these tables:
table1
1 - "a"
2 - "b"
table2
1 -
2 -
3 -
Now, I'm using the following code to compare the tables:
table2.MoveFirst
Do While Not table2.EOF
table1.Seek "=", table2!field2
If table1.NoMatch Then
go do a lot of things to find that information
Else
table2.Edit
table2!Field2 = table1!field2
table2.update
End If
table2.MoveNext
Loop
But the line
table2!Field2 = table1!field2
Is not working so well. I'm pretty sure I'm doing something wrong here, but I'm having problems finding a solution. I'm not even sure what I should google...
EDIT: Field 2 is indexed in table 1, so the 'seek' works.
A few notes.
Let us say you want all the records from Table2 where there is no match on a field called Field1:
sSQL = "SELECT Field1, FieldX FROM Table2 " _
& "LEFT JOIN Table1 " _
& "ON Table2.Field1 = Table1.Field1 " _
& "WHERE Table1.Field1 Is Null"
You could, of course, build the query in the query design window and fiddle around until is is just what you want, then switch to SQL view to get the right (ish) SQL string.
Dim rs As DAO.Recordset
Set rs = CurrentDB.Openrecordset(sSQL)
''table2.MoveFirst
Do While Not rs.EOF ''table2.EOF
''You do not need no match, all these records are missing a match
'' table1.Seek "=", table2!field2
'' If table1.NoMatch Then
go do a lot of things to find that information
rs.MoveNext
Loop
''This can all be done with one update query
'' Else
'' table2.Edit
'' table2!Field2 = table1!field2
'' table2.update
'' End If
'' table2.MoveNext
'' Loop
sSQL = "UPDATE Table2 " _
& "INNER JOIN Table1 " _
& "SET table2.Field2 = table1.field2 "
CurrentDB.Execute sSQL dbFailOnerror
Please treat the above as notes, not finished code.
But the line table2!Field2 = table1!field2 Is not working so well
...is not a good description of what goes wrong.
Does the code stop/crash at this line?
Does it run without errors, but do nothing / something else than you expected?
I suppose that you're using DAO Recordsets.
It's hard to give advice without more information, but I'll give it a try:
Is table2 completely empty? Your description looks like this:
table2
1 -
2 -
3 -
If yes, the whole loop is probably never executed at all.
Can the Recordset table2 be updated?
Not all types of Recordsets support this, it depends on how you create it. See MSDN: Recordset Object (DAO), there is a list of Recordset types at the beginning.
If it's not updateable, you should get an error when you call .Update.
If you're using DAO recordsets (as suggested by Christian) you can change the line
table2!Field2 = table1!field2
to
table2.Fields("Field2").value = table1.Fields("field2").value
I'm presuming both Field2's are of Text data type.
Related
I'm having two tables which is having claims data and user name respectively
Tblimport- Contains 10 claim no.s and.
tbl_Settings- Contains 3 username
. I want to assign those 10 claims to the 3 users
Condition: same claim should not assign to different users and everyone should get the claims equally.
I'm planning to use two loops with two record set.
but problem while using do loop it's coming the same claim id to every one
strqry = "Select [claimId] from Tblimport"
strqry2 = "Select [username] from tbl_Settings"
rs1.Open strqry2, cn1, adOpenStatic
rs2.Open strqry, cn2, adOpenStatic
rs2.MoveFirst
Do While Not rs2.EOF
If rs1.EOF Then
rs1.MoveFirst
End If
claim = CStr(rs2![ClaimID])
User = CStr(rs1![UserName])
Debug.Print claim & "-" & User
rs1.MoveNext
If rs1.EOF Then
rs1.MoveFirst
End If
rs2.MoveNext
Loop
Output I'm Getting
100021245-shp
100023633-abc
114552236-kjh
In the 4th time while loop coming to User = CStr(rs1![UserName]) it's showing Run time error 94, invalid usse of null
Tblimport
100021245
100023633
114552236
121223333
122333444
112123345
111223344
112344543
322344455
tbl_Settings
shp
abc
kjh
Seems your code mismatched recordsets for the ClaimID and UserId values. Or maybe I'm just confused.
Anyway what I think you want is to move through the ClaimID values, and for each of those sequentially fetch the "next" UserId. After you've fetched the "last" UserId, move back to the first again for the following ClaimID.
Sorry I can't think how to describe that more clearly. But what it come down to is revise your looping strategy.
rs2.MoveFirst
Do While Not rs2.EOF
'Claim = CStr(rs1![ClaimID])
'User = CStr(rs2![UserId])
Claim = CStr(rs2![ClaimID])
User = CStr(rs1![UserId])
Debug.Print Claim & "-" & User
rs1.MoveNext
If rs1.EOF Then
rs1.MoveFirst
End If
rs2.MoveNext
Loop
I have this code in MS Access (I did it in VBA becasue I didn't find the way to create a procedure in Access). What it does is simple, it takes a field form a table and replace the value in another table where the ID is the same.
How can I get this faster? It is currently taking 8 minutes more or less to get it done (processor is always under 20%, so it is not about processor power).
Set rst = CurrentDb.OpenRecordset("Tab_personal_2")
rst.MoveFirst
DoCmd.SetWarnings False
Do Until rst.EOF
DoCmd.RunSQL ("UPDATE Tab_personal_3 SET RFC = '" & rst("RFC") & "' WHERE Id = " & rst("Id"))
rst.MoveNext
Loop
You should be able to do this in a single query:
UPDATE Tab_personal_3 t3
INNER JOIN Tab_personal_2 t2 ON t2.ID = t3.ID
SET t3.RFC = t2.RFC
Of course, you can execute this query through VBA, if you wish. But storing the query allows Access to store the execution plan, and increase the speed on the query.
I believe a single update query will work if the tables share an ID field:
UPDATE Tab_personal_3 INNER JOIN Tab_personal_2 ON Tab_personal_3.ageing_collection = Tab_personal_2.Id SET Tab_personal_3.RFC = Tab_personal_2.RFC;
I have two tables (lets call them Parameters 1 and 2) which both have a many-many relationship with a third table (Options). I need to group the third table records into three groups:
Those exclusively related to [specific Parameter 1 record],
Those exclusively related to [specific Parameter 2 record] and
Those related to both [specific Parameter 1 record] and [specific Parameter
2 record].
I can ignore Option records not related to either of them.
I need to be able to specify which Parameter 1 and 2 records apply in a form (using combo boxes), and have VBA juggle the three lists in the background, updating them as the Option records they contain are "used" elsewhere in the form (with check boxes).
At the risk of asking a bad question I'll submit the code I have - even though it's not a code that fails, just the framework for one that isn't even finished enough to debug yet. I simply haven't got the tools to complete it, as I don't know what methods/properties of what things to use to do it, and can't seem to find the answers in my own research thus far. Comments directing me to other resources will be appreciated, even if you don't have an answer that you're sure is best practice.
Function SetOptions()
If IsNull(cmbParam1) Or IsNull(cmbParam2) Then
MsgBox "You must select both an Param1 and a Param2!", vbCritical, "Wait!"
Exit Function
End If
'Recordsets of allowed Options
Dim Param1Opt, Param2Opt, OverlapOpt
'create recordset of tblOption.Option(s) referenced in qryPr1Opt with Param1 from cmbParam1
Param1Opt = CurrentDb.OpenRecordset("SELECT tblPr1Opt.Option FROM tblPr1Opt " &_
"WHERE Param1 = '" & cmbParam1 & "';")
'create recordset of tblOption.Option(s) referenced in qryPr2Opt with Param2 from cmbParam2
Param2Opt = CurrentDb.OpenRecordset("SELECT tblPr2Opt.Option FROM tblPr2Opt " &_
"WHERE Param2 = '" & cmbParam2 & "';")
'create recordset of tblOption.Option(s) in qryOptOvrlp with Param2 and Param1 from form
OverlapOpt = CurrentDb.OpenRecordset("SELECT qryOptOvrlp.Option FROM qryOptOvrlp " &_
"WHERE Param1 = '" & cmbParam1 & "' AND Param2 = '" & cmbParam2 & "';")
OverlapNum = Param1Num + Param2Num
'Steps remaining:
'1. Get Param1Opt and Param2Opt to only include Options not in overlap
For Each oOpt In OverlapOpt
For Each aOpt In Param1Opt
If aOpt.Value = oOpt.Value Then
'filter this record out of Param1Opt
End If
Next aOpt
For Each gOpt In Param2Opt
If gOpt.Value = oOpt.Value Then
'filter this record out of Param2Opt
End If
Next gOpt
Next oOpt
'2. Get the data in Param1Opt, Param2Opt and OverlapOpt, as well as their
'corresponding Nums to be accessible/editable in other functions/subs
End Function
You can reference the values of controls in SQL statements run in the context of Access, using the following syntax:
Forms!FormName!ControlName
or using square brackets if needed:
Forms![Form Name]!ControlName
Therefore, instead of opening multiple recordsets, you can express each of your points as a single SQL statement with joined tables. You can then either set the RowSource of a combobox or listbox to the statement (if you are only using the statement in one place); or you can save the statement as an Access query, and use the query name as the RowSource (if you need the statement in multiple places).
Given the following schema:
and two comboboxes: cmbParam1 and cmbParam2 on a form named Form1, you can use SQL statements as follows:
1. Records from Options which match tblPr1Opt but have no match in tblPr2Opt
SELECT DISTINCTROW Options.Option
FROM (Options
INNER JOIN tblPr1Opt ON Options.Option = tblPr1Opt.Option)
LEFT JOIN tblPr2Opt ON Options.Option = tblPr2Opt.Option
WHERE tblPr2Opt.Option IS NULL
AND tblPr1Opt.Param1 = Forms!Form1!cmbParam1
Or using the query designer (note the arrow head next to tblPr2Opt; this indicates a left join):
2. Records from Options which match tblPr2Opt but have no match in tblPr1Opt:
SELECT DISTINCTROW Options.Option
FROM (Options
INNER JOIN tblPr2Opt ON Options.Option = tblPr2Opt.Option)
LEFT JOIN tblPr1Opt ON Options.Option = tblPr1Opt.Option
WHERE tblPr1Opt.Option IS NuLL
AND tblPr2Opt.Param2 = Forms!Form1!cmbParam2;
or in the query designer:
3. Records from Options which match on both:
SELECT Options.Option
FROM (Options
INNER JOIN tblPr1Opt ON Options.Option = tblPr1Opt.Option)
INNER JOIN tblPr2Opt ON Options.Option = tblPr2Opt.Option
WHERE tblPr1Opt.Param1 = Forms!Form1!cmbParam1
AND tblPr2Opt.Param2 = Forms!Form1!cmbParam2
Or in the query designer:
I am trying to iterate through a record-set twice. Once to write all of the non-zero results, followed by a second run through to write all the rows that have a zero in a particular column so that all of those rows with the value of 0 are at the end of the file. However since .EOF has been triggered with the first run through it is still "True" when I try to run through it again. What is the best way to run through it twice?
With CurrentDb.OpenRecordset(strSQL, dbOpenSnapshot)
Do Until .EOF
If .Fields(2) = 0 Then
Else
strCSV = ""
For x = 0 To .Fields.Count - 1
'No Qualifier
strCSV = strCSV & strDelimiter & Nz(.Fields(x), vbNullString)
Next x
'Eliminate Back to back strQualifiers or Qualifiers if changed
strCSV = Replace(strCSV, strQualifier & strQualifier, "")
strPrint = Mid(strCSV, Len(strDelimiter) + 1)
Print #intOpenFile, strPrint
End If
.MoveNext
Loop
Do Until .EOF
If Nz(.Fields(2), vbNullString) = 0 Then
strCSV = ""
For x = 0 To .Fields.Count - 1
'No Qualifier
strCSV = strCSV & strDelimiter & Nz(.Fields(x), vbNullString)
Next x
'Eliminate Back to back strQualifiers or Qualifiers if changed
strCSV = Replace(strCSV, strQualifier & strQualifier, "")
strPrint = Mid(strCSV, Len(strDelimiter) + 1)
Print #intOpenFile, strPrint
End If
.MoveNext
Loop
End With
To answer your question, just used .MoveFirst in between your two runs. But #Remou makes a good point that your can avoid this complication just by adding an ORDER BY into your SQL (+1)
Very old question but appears to have been active recently, and it's still coming up in searches, which is how I ended up here. And, as a new member, I need to start somewhere, so be kind.
The OP appears to be trying to code round a particular requirement, which is to have all the results in ascending numeric order, but with the zero items at the bottom. You can do this in SQL in one statement like this:
SELECT * FROM MyTable
ORDER BY MyNumField DESC, MyOtherSortField
WHERE MyNumField > 0
UNION ALL
SELECT * FROM MyTable
ORDER BY MyOtherSortField
WHERE MyNumField = 0
A UNION merges the results of two or more SELECT statements, removing duplicates. UNION ALL concatenates the results, and is more efficient, as it stops SQL removing duplicates between the two lists - in this case, we know they won't overlap due to the selection criteria being mutually exclusive.
You seem to be missing the point of a relational database, which is that it has no order other than the one you impose:
sSQL = "SELECT * FROM MyTable ORDER BY MyNumField DESC"
Set QDF = CurrentDB.CreateQueryDef ("DatOut", sSQL)
DoCmd.TransferText acExportDelim,,"DatOut","C:\Docs\Datout.csv"
I have been racking my brain over this all day today.
I have the following ASP code that uses a Request.Querystring input from a dropdown box
to launch a select statement. The querystrinch does show in the ?= URL but will only work on
columns in the Microsoft SQL DB that are numeric. I cant lookup names or simple 3 character fields.
CODE:
If Request.QueryString("m") > 0 Then
filterID = Request.QueryString("m")
filterColmn = "imDegree"
Else filterID = 0
End If
If filterID > 0 Then
SQlQuery = "SELECT * FROM v_InternImport WHERE iID IN (SELECT iID FROM v_InternImport WHERE " & filterColmn & " = " & filterID & ")"
End If
End If
I understand that this select statement as a sub select stament in it but I cant even get a staight reuturn from my DB. The select statement references the same view that populates the main asp page that loads before and the shows fine?
When you pass a string to SQL Server, you need to surround it with single quotes.
When you pass a number, you don't use the quotes.
So, when you say (summarizing)
SELECT * FROM table WHERE filterColumn = filterID
you should be sending a number.
To match a string:
SELECT * FROM table WHERE filterColumn = 'filterID'
This assumes that you have solved any other problems mentioned by the commenters about whether you even have a value in the filterID variable. I heartly concur with the recommendation to use parameterized queries.
Edit: The single quotes go inside the double quotes.
SQlQuery = "SELECT * FROM v_InternImport
WHERE iID IN (SELECT iID FROM v_InternImport
WHERE " & filterColmn & " = '" & filterID & "')"