473,387 Members | 1,483 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Deleting records from just one side of a join

patjones
931 Expert 512MB
Hi everyone,

I've been wrestling with this for a couple of days. I'm going to present a simple but equivalent scenario to the one I'm actually dealing with.

Suppose I have two tables: tblEmployees(ERN, last_name, first_name) and tblArchivedData(ERN, earned_date, earned_amount). The archived data table may have (and in practice will have) many dozens of records per employee (same ERN for many records). The employees table will contain just one record for each employee.

Next, suppose I have a bound sub-form in datasheet view, where my object is to display ERN, last_name, first_name, earned_date and earned_amount. I want to display all those records from the archive table.

If I set the datasheet recordsource to be the archive table, I get the ERN, earned_date and earned_amount just fine; but I also want to display the employee's name in the datasheet...even if it's appearing multiple times. When I do this by building a simple query involving a join between tblEmployees and tblArchivedData, and set the datasheet recordsource to that query, it works nicely.

The problem is that if I then cut a record from the datasheet, with the intention of deleting that record from tblArchivedData...it also cuts that employee's record from tblEmployees. I don't want this; tblEmployees is essentially functioning as a look-up table here, and I don't want anything deleted from it.

I sort of circumvented the problem by using DLookup to populate the names in the datasheet. But it's performance prohibitive, and you also lose other simple functionality like the ability to sort the datasheet based on last name.

Any ideas? Thanks.

Pat
Aug 29 '11 #1
20 2358
NeoPa
32,556 Expert Mod 16PB
As far as simply deleting a record from the subform goes, you're sort of stuck with deleting whatever's in the record source I'm afraid.

That said, you may be able to get around it by handling the BeforeDelConfirm event and coding it such that the records otherwise to be deleted are done via specific SQL, and then Cancel the event. Sound like a plan?
Aug 29 '11 #2
ADezii
8,834 Expert 8TB
I duplicated your conditions exactly as you have stated, and have not encountered the problem which you have described. Here are the details:
  1. tblEmployees and tblArchivedData are involved in a 1 to MANY Relationship in the following manner:
    Expand|Select|Wrap|Line Numbers
    1. tblEmployees.[ERN](1) ==> tblArchivedData.[ERN](MANY)
  2. Cascade Updates and Deletes are enforced on the Join between these Tables.
  3. The RecordSource for the Sub-Form is a Query whose SQL is:
    Expand|Select|Wrap|Line Numbers
    1. SELECT tblArchivedData.ERN, tblEmployees.last_name, tblEmployees.first_name, tblArchivedData.earned_date, tblArchivedData.earned_amount
    2. FROM tblEmployees INNER JOIN tblArchivedData ON tblEmployees.ERN = tblArchivedData.ERN;
  4. Link Child Fields: [ERN]
  5. Link Master Fields: [ERN]
  6. When I DELETE a Record in the Sub-Form, only that Record is DELETED, and has no effect on the Related Record on the Main Form.
Aug 29 '11 #3
patjones
931 Expert 512MB
For some reason I keep forgetting about the "Before..." events. It does sound workable. I'll try it this afternoon and let you know how it works out. Thanks.
Aug 29 '11 #4
patjones
931 Expert 512MB
@ADezii:

There is no related record in the main form. The main form has two date boxes that I type a date range into, which is used to narrow the sub-form recordsource query. But there is no parent-child relationship between the main and sub forms per se.

@NeoPa:

I tried both 'Before Del Confirm' and 'On Delete' with message boxes just to make sure they would fire. 'On Delete' fires, but 'Before Del Confirm' does not. This is the case regardless of whether I delete the record by right-clicking and using Cut, or use Delete in the Access window menu.
Aug 29 '11 #5
NeoPa
32,556 Expert Mod 16PB
Sounds ideal Pat. Use the Form_Delete event instead.

@ADezii
Your response deals with a typical use of main and subforms, but if you read the OP carefully you'll see that isn't claimed in this case. It appears all the data is shown exclusively on the subform in this case.
Aug 29 '11 #6
patjones
931 Expert 512MB
Right, this isn't a typical form/sub-form usage. The end user has a certain combination of needs (including deletion and editing capabilities) that requires this arrangement. Otherwise I would use a list box. Thanks.

I'll try Form_Delete.
Aug 29 '11 #7
NeoPa
32,556 Expert Mod 16PB
@Pat
This is a side-issue I know, but if the main form is not bound is there really any need for a subform? The managing controls could possibly be held in the Header section of the form and that would make referencing elements from with the code that much more straightforward.

Just a thought. You obviously know the project better than I do, but I know that's a design which developers often overlook.
Aug 29 '11 #8
patjones
931 Expert 512MB
I changed my code to use the join method rather than the DLookup method in order to continue this discussion.

The subform's 'On Delete' fires as I mentioned previously, but even when I execute a SQL DELETE specifying just the tblArchivedData part of the record, it still deletes the tblEmployees part of the record also. I think this is because when the user initiates the process, Access deletes the record regardless of what code happens to be associated with the event.

The main form 'On Delete' event does not fire.

I have to say that I completely understand the logic of using the 'Before Del Confirm' event. I could execute my SQL to delete just the one side of the join, then say Cancel = True in order to cancel whatever Access would have done with the delete. But that event isn't firing. Truly maddening!
Aug 29 '11 #9
NeoPa
32,556 Expert Mod 16PB
Are you setting Cancel = True in your Form_Delete() event procedure when you delete the records with the specific SQL?

Also, can you confirm whether or not you are staying with the main/sub approach rather than the simpler main as suggested - so we know exactly where we are?
Aug 29 '11 #10
patjones
931 Expert 512MB
I'm sticking with the main/sub approach.

I thought perhaps that the reason the 'Before...' event wasn't firing is that I did not have the Confirm Record Changes box checked in Access options. The help page says the event won't run if that's the case, so I turned that option on but it still didn't make a difference.

BUT, this works:

Expand|Select|Wrap|Line Numbers
  1. Private Sub Form_Delete(Cancel As Integer)
  2.  
  3. CurrentDb.Execute "DELETE FROM dbo_tblArchivedData WHERE dbo_tblArchivedData.ERN = " & Me.txtERN.Value
  4. Cancel = True
  5.  
  6. End Sub

...and the tblEmployees side of my record is preserved. The only problem is that the entire record remains visible in the subform. Doing a Me.Requery gives me Error 3246: Operation not supported in transactions.
Aug 29 '11 #11
NeoPa
32,556 Expert Mod 16PB
Pat:
I'm sticking with the main/sub approach.
8-) We're on the same page as to what your design is at least.

Pat:
BUT, this works:
You say that like it weren't what I suggested :-S

Pat:
Doing a Me.Requery gives me Error 3246: Operation not supported in transactions.
Now there you have a real problem. I came across this one the other day on here and frankly I haven't thought of a way around it yet (if there even is one).

If you want to attach a copy so that I can play around with your database and experiment then I'd be happy to look at it for you. The usual suggestions apply for attaching databases (Attach Database (or other work)).
Aug 30 '11 #12
NeoPa
32,556 Expert Mod 16PB
I had some further thoughts on this overnight, and it seems that the form itself, understandably, is locking the record(s) it's preparing to delete.

Getting around this will be interesting. Worst case scenario I can think of now is to cancel the Delete then use the Timer to run the SQL very shortly afterwards. I'd need to play for a while and experiment before coming to a conclusion as to the best way to handle though.
Aug 30 '11 #13
ADezii
8,834 Expert 8TB
Doing a Me.Requery gives me Error 3246: Operation not supported in transactions.
Wouldn't dynamically changing the RecordSource of the Sub-Form do the trick, after the Deletion?
Aug 30 '11 #14
NeoPa
32,556 Expert Mod 16PB
One of the possible ideas to check if/when I get hold of a copy of the database. I'm not convinced the SQL delete even works yet in the current circumstances. All determinable with the database to hand though.
Aug 30 '11 #15
patjones
931 Expert 512MB
OK, just got in the office...

I was just a little surprised that 'On Delete' worked because it's basically what I was trying to do before. And now suddenly, it works. I'm not complaining, I'm just expressing befuddlement.

This is an Access 2007 database linked to SQL Server tables. Before I go through the trouble of converting it 2003 for you and making the tables local, I want to try a couple of things:

First, ADezii's suggestion of reassigning the recordsource. I think this will work although I feel that it's redundant because it gets assigned when the subform is first populated.

Second, per your Timer suggestion, NeoPa, I want to see if this is just a timing issue. There is an internal transaction taking place and perhaps it simply needs to finish before I can Requery.

Stay tuned. Thanks guys.
Aug 30 '11 #16
NeoPa
32,556 Expert Mod 16PB
That's absolutely fine Pat. Do any testing you want first. There's only point in my doing it if you can't. You finding the solution is a far better result at the end of the day ;-)

My thinking ref the Timer approach is that while within the code that processes the Delete requested, the record is likely to be locked. Once that's completed fully, I'm hoping it's possible for code to run with full access to the dataset.

PS. I never read what you said as complaining. Simply as indicating you maybe hadn't understood that it was one of the things I'd suggested earlier in the thread. I've noticed things are easily missed in threads, and sometimes long discussions follow where both sides are communicating at cross-purposes, just to realise eventually it was a simple matter of one party missing something that had already been said much earlier. It's the nature of the game I suppose, but I do try to ensure any such misunderstandings are avoided where possible.
Aug 30 '11 #17
patjones
931 Expert 512MB
I finally found someone on another board who had precisely the same problem. Allen Browne suggested to him that he set Allow Deletions on the form to No, and put the required deletion code behind a command button. I can't argue with that. I'll post my final code when I have it. Thanks.
Aug 30 '11 #18
NeoPa
32,556 Expert Mod 16PB
8-) That's certainly a solution. I'd prefer one that's more intuitive personally, but if Allen Browne (A great Access MVP) suggests that then it certainly confirms finding an intuitive solution isn't straightforward at least. Obviously my preference doesn't (nor should it) count for twopence in this thread.
Aug 30 '11 #19
patjones
931 Expert 512MB
I agree. I try to develop streamlined forms, with a minimal number of controls. Unfortunately, this project is overdue and I have to go the route of using the button. The code behind the button is:

Expand|Select|Wrap|Line Numbers
  1. Private Sub cmdDeleteRecord_Click()
  2.  
  3. On Error GoTo Err_cmdDeleteRecord_Click
  4.  
  5. Dim lngERN As Long: lngERN = Nz(Me.frmReportedData.Form!txtERN, 0)
  6.  
  7.     If lngERN = 0 Then
  8.         MsgBox "Please ensure that the preview window is populated and select a record for deletion.", vbOKOnly + vbExclamation, "Current Record Deletion": Exit Sub
  9.     Else
  10.         If MsgBox("Delete the record for " & Me.frmReportedData.Form!officer_name & "?", vbOKCancel + vbQuestion, "Current Record Deletion") = vbOK Then
  11.             CurrentDb.Execute "DELETE FROM dbo_tblArchivedData WHERE dbo_tblArchivedData.ERN = " & lngERN
  12.             Me.frmReportedData.Form.Requery
  13.         End If
  14.     End If
  15.  
  16. Exit_cmdDeleteRecord_Click:
  17.     Exit Sub
  18.  
  19. Err_cmdDeleteRecord_Click:
  20.     MsgBox err.Number & " " & err.Description, vbExclamation + vbOKOnly, "Current Record Deletion"
  21.     Resume Exit_cmdDeleteRecord_Click
  22.  
  23. End Sub

Thanks again guys for the help!

Pat
Aug 30 '11 #20
NeoPa
32,556 Expert Mod 16PB
No worries Pat :-)

It's always more rewarding to help those who help others (Not that other members don't in other ways - but I'm not aware of that).
Aug 30 '11 #21

Sign in to post your reply or Sign up for a free account.

Similar topics

6
by: Amit Kela | last post by:
I am using ASP with SQL for my database. The problem I have is that even after I have ordered certain items from the shopping cart table on the webpage, I cannot remove them - that is the entire...
1
by: Mark | last post by:
This question refers to a main form with a continuous form subform. After an error occurs after entering several records in the subform, how can I delete all the data in the main form and all the...
3
by: Nathan Bloom | last post by:
Hi, I have a data entry form (access 2000) that also allows the user to add, update, and delete records from the form. The Delete action is carried out in an event procedure and has the...
1
by: Coy Howe | last post by:
This one seems bizarre! We have a database consisting of a main table and 12 - 15 "sub" tables, which are connected via cascading relationships. The database performs many complex calculations...
1
by: KC | last post by:
Hello, I am using Access 2002. WinXP, Template from MS called Orders Mgmt DB. I have tweaked this DB to work for our small co. It has worked pretty well up until I made the mistake of deleting...
1
by: KC | last post by:
Hello, I am using Access 2002. WinXP, Template from MS called Orders Mgmt DB. I have tweaked this DB to work for our small co. It has worked pretty well up until I made the mistake of deleting...
2
by: MLH | last post by:
DELETE tblPreliminaryVINs.* FROM tblPreliminaryVINs INNER JOIN tblVehicleJobs ON tblPreliminaryVINs.PVIN = tblVehicleJobs.SerialNum; The above SQL does not work for me. I get an error I cannot...
1
by: svgeorge | last post by:
I AM TRYING TO DELETE RECORDS FROM THE SQL SERVER TABLE, I AM USING THE COMMAND BELOW TO DELETE THOSE 71 RECORDS BUT MY WHOLE TABLE GOT DELETED AND HAD TO RECOVER FROM BACKUP.. SO WHAT IS WRONG...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.