سؤال

آسف على جدار نص الرجال ولكن هذا يتطلب expliaining, الكثير من التعليمات البرمجية إلى آخر...

أنا استيراد عرض ثابت الملفات إلى الوصول في الأساليب التي تتطلب إدخال البيانات.استيراد الملف باستخدام transferText إلى قسمين المواصفات (تلك العالمية ، والآخر هو ظرف خاص).

لدي وظيفة يستخدم DAO إلى دورة خلال كل مجال الكائنات في TableDefs لبناء جدول مكرر بما في ذلك تعداد PK لذلك لدي القدرة على تحرير هذه السجلات.لقد دفع البيانات في هذا الجدول مع إدراج.

يعمل كبيرة.تم العثور على أخطاء, يذهب المستخدم إلى إدخال البيانات يدويا الصحيح منها الذي يدق غربلة 400 حرف خطوط وإعادة تنظيم كل شيء بالطريقة التي من المفترض أن تكون.يعمل كبيرة!

المشكلة:عند إدخال البيانات يتم إجراء تغييرات على ارتكاب الضغط على زر الذي يدعو وظيفة داخل وحدة خارج النموذج.فإنه يغلق نموذج إدخال البيانات ويدفع المعلومات مرة أخرى إلى الجدول الأصلي ناقص autoincremented PK, و هو من المفترض أن إسقاط نسخ الجدول مع هوية, وإنشاء واحدة جديدة في البحث مرة أخرى عن الأخطاء...

فإنه يدفع العودة إلى الأصل على ما يرام, ولكن ذلك لن تسقط معرف الجدول.دائما يعود لي مع رسالة تشير إلى هذا الجدول هو مؤمن.لقد لاحظت الجدول indefiniatly محجوز إلى جميع وظائف/subs الخروج.في أي وقت التنقل خلال التعليمات البرمجية لا يمكن حذفها يدويا بمجرد تنفيذ الانتهاء من أنا قادرة على إزالته.

وأنا على افتراض أنه منذ دعوت هذا من خلال الأوامر في شكل القفل لن يفرج عنه حتى كل رمز التشطيبات و شكل إنهاء يمكن أن يطلق عليه شيء.أي أفكار ؟ نعم هذا هو جدا الهمجي لكنه يعمل بشكل جيد جدا, أنا فقط بحاجة إلى أن تكون قادرة على مزق هذا الجدول الآخر من كوكب الأرض حتى أستطيع أن redrop نسخة محدثة...

في أسوأ الأحوال لا يمكن أن تجعل المستخدم إغلاق النموذج وضرب آخر زر في النموذج الرئيسي ولكن هذا يتم تصميمه بشكل كبير مع المستخدم compitence في الاعتبار.ولكن هذا الآن اهتمامي الكامل و ترغب على الأقل إيجاد حل حتى لو انها ليست الأمثل واحدة.

-تحرير-

شكلين تستخدم في هذه المشكلة

FormA (Role: Load in and search for problems)

Examine button is pressed that:

 - Uses TextTransfer based on predefined specs into tempExtract to
       import the file

 - DAO fires off on the Fields collection in tableDefs for
   tempExtract, creates new table tempExtractID

 - Performs searches through the file to find errors.  Errors are saved to
   a table Problem_t.  Table contains Problem_ID (Set from the ID field
   added to tempExtractID) and Description

 - Execution of these tasks is successfully requerying the initial
   form to showing a list of problems and number of occurances.  A button
   gains visibility, with onClick that opens the form DataEntry.            

 - At this point in the code after DAO execution, I can DROP the table
   tempExtractID.  DAO is NOT used again and was only used to build a new table.

FormB - نموذج إدخال البيانات

بمجرد أن أفتح هذا شكل الجدول tempExtractID يصبح مؤمنا و لا يمكن إسقاط الجدول.في مصدر السجل على شكل querys tempExtractID ضد الهوية في Problems_t العودة فقط ما نحن بحاجة إلى مفتاح.

أنا لا يمكن إسقاط الجدول حتى شكل بالكامل إنهاء.زر في نموذج إدخال البيانات يتم الضغط على ارتكاب التغييرات التي توجد فقط 5 الأسطر من التعليمات البرمجية التي تحصل على الحريق قبل أن أحصل على قفل خطأ.

*Xargs refers to the list of Field names pulled earlier through DAO.  As DAO loops through Field objects, the physical names are added to an Xargs String which is placed in this table.  Basically everything but the AutoNumber is being inserted back

    docmd.Close acForm, "frmDataEntry", acSaveNo
    call reInitializeExtract
         > docmd.RunSQL "DELETE FROM tempExtract"
         > docmd.RunSQL "INSERT INTO tempExtract SELECT (" & DLookup("Value", "CONFIG_t", "Item = 'Xargs'" & ") FROM tempExtractID"
    docmd.DeleteObject acTable, "tempExtractID"

هذا هو رمز فقط التي يتم تشغيلها بين الوقت حيث شكل فتح (حيث الجدول الأول يحصل على تأمين) ولا يزال مغلقا حتى جميع الغواصات & وظائف الانتهاء.

هل كانت مفيدة؟

المحلول

أقترح وضع مصدر السجل للنموذج إلى vbNullString ثم حذف الجدول.هذا يجب أن تعمل ما لم يكون لديك أيضا comboboxes وما إلى ذلك لا بد أن هذا الجدول.

نصائح أخرى

دون رمز من الصعب قول ذلك, ولكن إذا كنت تستخدم DAO, تحتاج إلى تنظيف التعليمات البرمجية الكائنات.وهذا يعني وضع شيء الخاص بك كائنات قاعدة البيانات الختامية وتحديد إلى أي شيء أي كائنات مجموعة السجلات.

  Dim db As DAO.Database
  Dim rs As DAO.Recordset

  Set db = DBEngine.OpenDatabase("[path to database]")
  Set rs = db.OpenRecordset("[SELECT statement]")
  rs.Close
  Set rs = Nothing
  db.Execute("[DML or DDL statement]", dbFailOnError)
  db.Close
  Set db = Nothing

  Set db =CurrentDB
  Set rs = db.OpenRecordset("[SELECT statement]")
  rs.Close
  Set rs = Nothing
  Set db = Nothing  ' you don't close a db variable initialized with CurrentDB

في حين VBA المفترض لتنظيف هذه الكائنات عندما يخرجون من نطاق, ليس 100% موثوق بها (لأن VBA يستخدم الإشارة عد إلى تتبع ما إذا كان كائن يمكن أن يكون صدر و لا تعرف دائما عند جميع المراجع التي تم تطهيرها).

الأشياء تركت مفتوحة المصدر الأكثر احتمالا من الأقفال ، لذلك يجب عليك التأكد من أنك تقوم بتنظيف وجوه الخاص بك المتغيرات بعد الانتهاء من معهم.

تحرير بعد التأكد من أن كنت تستخدم DoCmd.RunSQL:

باستخدام DoCmd.RunSQL هو على الأرجح سبب المشكلة.هو بالتأكيد شيء أن يأخذ الخاص بك برنامجي إدارة الاتصالات الخاصة بك.إذا كنت تستخدم DAO بدلا من ذلك سيكون لديك السيطرة على اتصال ، وكذلك تجنب الحقيقي شرك DoCmd.RunSQL ، وهو أنه لا التعامل مع الأخطاء.إذا DML أو DDL لا يمكن إكمال بنجاح كامل, كل شيء يجب أن تفشل.على سبيل المثال, إذا كنت إلحاق 100 السجلات و 10 منهم تفشل الرئيسية الانتهاكات ، DoCmd.RunSQL سوف بشفافية إلحاق 90 وليس تقرير 10 الفشل.انه نفس الشيء مع التحديثات وغيرها DML/DDL.DoCmd.RunSQL "مفيد" بصمت يكمل العديد من التحديثات ، وترك لديك أي فكرة أن فشل في إكمال.

تمنح في بعض الحالات قد ترغب في أن يحدث ذلك ، على سبيل المثال ، إذا كنت إلحاق السجلات التي تعرف قد PK التصادم و لا تريد أن تنفق دورات وحدة المعالجة المركزية على join أن يلغي مكررة من مجموعة من السجلات أنت إلحاق.

ولكن في معظم الوقت, هذا ليس هو الحال.

كما قلت في تعليقي أعلاه ، يمكنني استخدام وظيفة التي تم تصميمها بشفافية محل DoCmd.RunSQL و يستخدم DAO تنفيذ بيان ومعالجة الأخطاء.كنت قد نشرت عدة مرات على ذلك (هنا واحد), و هنا في النسخة التي لدي في استخدام الإنتاج في بلدي حاليا الأكثر نشاطا تطوير المشروع:

  Public Function SQLRun(strSQL As String, Optional db As Database, _
       Optional lngRecordsAffected As Long) As Long
  On Error GoTo errHandler
    Dim bolCleanup As Boolean

    If db Is Nothing Then
       Set db = CurrentDb
       bolCleanup = True
    End If
    'DBEngine.Workspaces(0).BeginTrans
    db.Execute strSQL, dbFailOnError
    lngRecordsAffected = db.RecordsAffected
    'DBEngine.Workspaces(0).CommitTrans

  exitRoutine:
    If bolCleanup Then
       Set db = Nothing
    End If
    SQLRun = lngRecordsAffected
    'Debug.Print strSQL
    Exit Function

  errHandler:
    MsgBox "There was an error executing your SQL string: " _
       & vbCrLf & vbCrLf & Err.Number & ": " & Err.Description, _
       vbExclamation, "Error in SQLRun()"
    Debug.Print "SQL Error: " & strSQL
    'DBEngine.Workspaces(0).Rollback
    Resume exitRoutine
  End Function

(المعاملات علق بها لأنها كانت تسبب المشاكل التي لم يكن لدي الوقت لاستكشاف)

يمكنك استبدال هذه الخطوط لك:

  DoCmd.RunSQL "DELETE FROM tempExtract"
  DoCmd.RunSQL "INSERT INTO tempExtract SELECT (" _
    & DLookup("Value", "CONFIG_t", "Item = 'Xargs'" & ") FROM tempExtractID"

...مع هذا:

  SQLRun "DELETE FROM tempExtract"
  SQLRun "INSERT INTO tempExtract SELECT (" _
    & DLookup("Value", "CONFIG_t", "Item = 'Xargs'" & ") FROM tempExtractID"

يمكنك أيضا القيام بذلك:

  Debug.Print SQLRun("DELETE FROM tempExtract") & " records deleted."
  Debug.Print SQLRun("INSERT INTO tempExtract SELECT (" _
    & DLookup("Value", "CONFIG_t", "Item = 'Xargs'" _
    & ") FROM tempExtractID") & " records inserted."

لأن وظيفة ترجع .RecordsAffected لكل التنفيذ, يمكنك الطباعة إلى الإطار الحالي أو يمكنك تعيين قيمة الإرجاع إلى متغير أو تمرير متغير موجودة من خلال العمل مع هذا المتغير وبالتالي:

  Dim lngRecordsAffected As Long
  ...
  Call SQLRun("DELETE FROM tempExtract", , lngRecordsAffected)
  Debug.Print lngRecordsAffected & " records deleted."
  Call SQLRun("INSERT INTO tempExtract SELECT (" _
    & DLookup("Value", "CONFIG_t", "Item = 'Xargs'" _
    & ") FROM tempExtractID", , lngRecordsAffected)
  Debug.Print lngRecordsAffected & " records inserted."

وهذه النقطة هي أنه إذا كانت هناك أخطاء في تنفيذ بيان كل شيء سوف تفشل (و تظهر رسالة خطأ -- قد ترغب في تغيير ذلك أنه إذا كان هناك خطأ فإنه يعود -1 أو بعض من هذا القبيل بدلا من ظهرت رسالة MsgBox).

يمكنني استخدام هذه الدالة في معظم الأحيان عن طريق تمرير في مرحلة ما قبل قاعدة البيانات المخزنة مؤقتا متغير, لذلك أنا لا أريد أن تنظيفه بعد ذلك.إذا كنت تستخدم قاعدة بيانات مختلفة أخرى من CurrentDB(), كنت حقا لا تريد أن تأكد من أي قاعدة بيانات متغير لافتا إلى الخارجية db مغلق تعيين إلى لا شيء.دون أن الأقفال الحفاظ على أعلى مستوى كائنات قاعدة البيانات ، LDB الملفات لا تزال مفتوحة ونشطة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top