2011-11-01 4 views
2

다음 코드를 실행하여 레코드 세트를 반복하고 필요한 부분을 업데이트합니다.Access VBA - 런타임 오류 '3197'

Microsoft Access 데이터베이스가 MySql 백엔드에 연결되어 있습니다.

Private Sub test() 

Dim rs As DAO.Recordset, rsCnt As Long, i As Long 
Set rs = CurrentDb.OpenRecordset("qryMyQuery", DB_OPEN_DYNASET) 
rs.MoveLast 
rsCnt = rs.RecordCount 
rs.MoveFirst 
For i = 1 To rsCnt 

rs.Edit 
rs!MyFieldInTable = "test" 
rs.Update 

Next i 

End Sub 

나는 내가 이전 백업 뽑아 Access 데이터베이스가 손상되었을 수 있습니다 생각하지만이 같은 일을하고 있어요 :

The Microsoft Office Access database engine stopped the process because you and another user are attempting to change the same data at the same time.

코드는 다음과 같습니다 :이 코드를 실행 할 때마다 나는 다음과 같은 오류가 발생합니다 그러면 MySql 문제라고 생각하게됩니다.

다른 MySql 테이블에 링크 된이 데이터베이스의 다른 버전에서 동일한 코드를 사용하므로 정상적으로 작동합니다.

또한 쿼리를 열면 레코드 세트가 쿼리의 데이터를 아무런 문제없이 편집 할 수 있습니다.

첫 번째 루프에서 rs! MyFieldInTable을 업데이트하면 오류가 발생합니다.

답변

4

레코드 집합의 다른 레코드로 이동하는 것으로 나타나지 않습니다. 단순히 i을 증가 시키면 다음 레코드로 이동하지 않습니다. 보다 전통적인 접근 방식은 다른 변수 (irsCnt)가 필요없이 레코드 세트를 반복하는 것입니다. 내가 검색을 조금 후

Dim rs as DAO.Recordset 
Set rs = CurrentDb.OpenRecordset("qryMyQuery", DB_OPEN_DYNASET) 
rs.moveFirst 
Do Until rs.EOF 
    rs.Edit 
    rs!FieldNameHere = "test" 
    rs.Update 
    rs.MoveNext 
Loop 

편집 이 문제와 유사한 것으로 보인다 this thread을 가로 질러왔다. 스레드의 맨 아래에서 "고급"탭을 선택하고 "일치하는 행 반환"옵션을 선택하여 MySQL DSN에 대한 ODBC 설정을 수정하라는 제안을합니다. 또한이 게시물은 링크 된 테이블을 삭제 한 다음 Access 데이터베이스에 다시 연결한다고 말합니다. 나는 과거에 MySQL을 사용하지 않았기 때문에이 방법이 효과가 있을지 모르겠으므로주의해서 진행하십시오!

당신은 또한 전혀 도움이 있는지 확인하기 위해 옵션을 잠금 레코드의 dbOptimistic 플래그를 사용하도록 레코드를 변경하려고 할 수 있습니다 :

set rs = CurrentDB.OpenRecordSet("qryMyQuery", DB_OPEN_DYNASET, dbOptimistic)

+0

멋지게 완료되었습니다. + 1 – XIVSolutions

+0

+1 @XIVSolutions과 마찬가지로 새로운 답변이로드되었다는 메시지를 받았을 때 비슷한 답을 쓰고있었습니다. – mwolfe02

+0

또한 내가 틀렸다면 나를 수정 해주세요.하지만 rs.Edit가 루프 안에 들어가야한다고 생각합니다. DAO 도움말 파일에서 : ** Edit Method : ** * 후속 편집을 위해 ** 현재 레코드 **를 업데이트 가능한 Recordset 개체에서 복사 버퍼로 복사합니다. * – mwolfe02

1

나는에 이것을 시도하려면 여기를 MySQL이없는, 하지만 rs.Update 메서드가 실행 된 후 코드가 레코드 집합을 전진시키지 않는 것처럼 보입니다. 그래서 당신은 가장 강력한 레코드에서 같은 필드를 우회하려고합니다.

는 rs.Update 후이 줄을 추가하는 데 도움이

rs.MoveNext 

희망을.

+0

또한 Tim Lentine이 게시 한 코드는보다 우아한 방법입니다. 그는 여전히 내 대답을 쓰는 동안 게시했습니다. – XIVSolutions

+1

사람들이 downvote에 가려고한다면, 그들이 어떤 이유로 투표를 동반한다면 그것은 단지 peachy 일 것입니다. 그냥 제게 ' – XIVSolutions

1

CurrentDb()에서 직접 가져 오는 대신 개체 변수에서 OpenRecordset을 CurrentDb()로 설정해보십시오.

Dim rs as DAO.Recordset 
Dim db As DAO.Database 
Set db = Currentdb 
Set rs = db.OpenRecordset("qryMyQuery", DB_OPEN_DYNASET) 
rs.moveFirst 
Do Until rs.EOF 
    rs.Edit 
    rs!FieldNameHere = "test" 
    rs.Update 
    rs.MoveNext 
Loop 

그 이유는 CurrentDb의 작업이 "블록 설정 안 됨"에 대한 오류를 직접 throw 할 수 있다는 것입니다. 하지만 대신 개체 변수를 사용할 때 오류가 발생하지 않습니다. ISTR OpenRecordset은 이것이 문제가되었던 작업 중 하나였습니다.

UPDATE qryMyQuery SET FieldNameHere = "test"; 

그러나, 나는 예는 레코드 접근 방식이 유용 실제 상황에 대한 프록시 의심 :

또한, 내 인상은 당신의 접근 방식에 해당하는 작업을 수행하는 번거로운 방법이었다. 여전히 UPDATE 문을 실행할 때 동일하거나 다른 오류가 표시되는지 궁금합니다.

이 문제가 계속 발생하면 qryMyQuery에 대한 SQL보기를 표시하는 데 도움이 될 수 있습니다.

2

두 가지를 시도해 볼 수 있습니다. 첫째, 레코드 집합을 열 때 dbSeeChanges 옵션을 추가하십시오 :

Dim rs as DAO.Recordset, db As DAO.Database 
Set db = Currentdb 
Set rs = db.OpenRecordset("qryMyQuery", dbOpenDynaset, dbSeeChanges) 
Do Until rs.EOF 
    rs.Edit 
    rs!FieldNameHere = "test" 
    rs.Update 
    rs.MoveNext 
Loop 

다른 옵션을 @HansUp 제안으로, 동적 레코드 대신 SQL UPDATE 문을 사용하는 것입니다. 레코드 세트를 스냅 샷으로 열면 레코드에 대한 변경 사항이 레코드 세트 자체에 영향을 미치지 않도록하는 것이 중요합니다.

Dim rs as DAO.Recordset, db As DAO.Database 
Set db = Currentdb 
Set rs = db.OpenRecordset("qryBatchPayments", dbOpenSnapshot) 
Do Until rs.EOF 
    db.Execute "UPDATE Payments " & _ 
       "SET DCReference='test' " & _ 
       "WHERE PaymentID=" & !PaymentID, dbFailOnError 
    rs.MoveNext 
Loop 
0

MySql 레코드에있는 데이터와 동일한 데이터를 저장하려고하면 Access에서 이러한 종류의 오류가 표시된다는 것을 발견했습니다. 이 스레드에서 몇 가지 제안을 시도했지만 도움이되지 않았습니다.

간단한 해결책은 수동 타임 스탬프를 사용하여 약간 다른 데이터를 저장하는 것입니다. 여기가 MySQL의 테이블에 자동 시간 스탬프를 시도했지만 때 새 항목 데이터를 도움이되지 않았다

i = 10 
    timeStamp = Now() 
    Do Until Employee.EOF 
     Employee.Edit 
     Employee!SortOrderDefault = i 
     Employee!LastUpdated = timeStamp 
     Employee.Update 
     i = i + 10 
     Employee.MoveNext 
    Loop 

정렬 순서 필드를 부풀어 오르고, 10, 20, 30로 설정의 예입니다 ... 이전 것과 동일합니다.

+0

같은 것을 경험했습니다. 이 MySQL 버그 보고서에서 언급 : http://bugs.mysql.com/bug.php?id=46406 Access가 업데이트 쿼리를 작성하는 방식 때문에 발생하는 것으로 보입니다. 'timestamp' 컬럼을 사용하여 클라이언트 측 또는 서버 측에 제안하는 것처럼 해결할 수 있습니다. – AronVanAmmers

0

약간의 도움이되는 힌트는 비트가 Microsoft Access에 SQL 테이블을 연결할 때 비트가 매우 이해하기 쉽기 때문에 비트가 매우 좋지 않음을 의미합니다. . 임의의 비트 데이터 유형을 int (정수)로 변경하고 테이블을 다시 연결하여 테이블을 정리하십시오. 또한 귀하의 VBA 코드에 항상 1 또는 0 (예/아니요 또는 true/flase가 아닌)이 포함되어 있는지 확인하십시오. 그렇지 않으면 Microsoft Access에서 True로 업데이트하려고하기 때문에 연결된 SQL 테이블에 대한 업데이트가 실패합니다/거짓 또는 예/아니오와 SQL은 그것을 좋아하지 않을 것입니다.

0

나는 또한 동일한 문제가 있었다;

**rst.lockedits = true** 
rst.edit 
rst.fields(...).value = 1/rst!... = 1 
rst.update 
**rst.lockedits = false** 

이 (예 형태에서와 같이) 단지 개방 데이터 간의 충돌을 해결 보인다 코드들을 업데이트 : 그들을이 dao.recordset를 사용하여 그 코드를 추가 해결.

불쌍한 영어로 죄송합니다 ... 많이 읽었지만 결코 배웠습니다! 나는 단지 이탈리아 사람이다.

+0

코드를 SQL 문으로 변경 한 경우주의하십시오. Form_Unload 이벤트는 SQL로 변경 한 동일한 데이터를 업데이트하려고 시도하지만 관리 할 수없는 오류가 발생합니다. 이것은 모든 앱을 바꿀 수 있습니다. – AntonioFico

관련 문제