2015-08-27 9 views
5

मैंने इस साइट का काफी उपयोग किया है, लेकिन यह पहला प्रश्न है जिसे मैंने पोस्ट किया है, उम्मीद है कि मैं पर्याप्त जानकारी दे सकता हूं। मुझे कोई प्रासंगिक उत्तर नहीं मिल रहा है क्योंकि कोई फर्क नहीं पड़ता कि मैं क्या खोजता हूं, मुझे लूपिंग कोड से संबंधित विभिन्न उत्तर मिलते हैं।वर्कशीट्स के माध्यम से वीबीए अनचाहे लूप

कुछ पृष्ठभूमि: मैंने अपने कार्यस्थल में कुछ वस्तुओं को ट्रैक करने के लिए एक एक्सेल दस्तावेज़ तैयार किया है (बाद में मास्टर दस्तावेज़ के रूप में संदर्भित)। चूंकि पिछले ट्रैकर ने उपयोगकर्ताओं को किसी भी समय कुछ भी संपादित करने की अनुमति दी है, इसलिए मैंने यह सुनिश्चित करने के लिए फॉर्म का उपयोग किया है कि सभी जानकारी सही तरीके से दर्ज की गई है और सुरक्षित रूप से संग्रहीत की गई है। मास्टर दस्तावेज़ में प्रत्येक आइटम के लिए एक अलग एक्सेल कार्यपुस्तिका है (इसके बाद इसे आइटम दस्तावेज़ के रूप में संदर्भित किया जाता है)।

मास्टर दस्तावेज़ में कई चादरें हैं जो प्रत्येक बार सक्रिय होने पर कोड चलाती हैं (क्योंकि उन्हें अपडेट करने की आवश्यकता होती है)।

जैसा कि प्रत्येक दस्तावेज़ दस्तावेज़ में कुछ वीबीए कोड है जो मास्टर दस्तावेज़ के साथ डेटा समन्वयित करने में महत्वपूर्ण है, मैंने एक चेतावनी वर्कशीट जोड़ा है जो दिखाया गया है कि आइटम दस्तावेज़ मैक्रोज़ के बिना खोला गया है। इसमें कार्यपुस्तिका को खोलने से पहले, सहेजने से पहले और घटनाओं को सहेजने के बाद केवल यह सुनिश्चित किया जाता है कि केवल मैक्रोज़ के बिना चेतावनी दिखाई दे। यहाँ प्रत्येक घटना के लिए कोड (स्पष्ट रूप से ThisWorkbook मॉड्यूल में रखा)

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) 

    Auto_Open 

    'This is for sync (Master Document checks for text file to see if any changes have been made to Item Document) 
    If booChange = True Then 
     Dim oFile As Object 
     Set oFile = fso.CreateTextFile(strTextFile) 
     SetAttr strTextFile, vbHidden 
     booChange = False 
    End If 

    'Turn off Screen Updating 
    Application.ScreenUpdating = False 

    'Show warning sheet 
    Sheets("Warning").Visible = xlSheetVisible 

    'Hide all sheets but Warning sheet 
    For Each sh In ThisWorkbook.Worksheets 
     If Not sh.Name = "Warning" Then sh.Visible = xlVeryHidden 
    Next sh 

End Sub 

Private Sub Workbook_AfterSave(ByVal Success As Boolean) 

    'Show all sheets 
    For Each sh In ThisWorkbook.Worksheets 
     sh.Visible = xlSheetVisible 
    Next sh 

    'Hide the warning sheet 
    Sheets("Warning").Visible = xlVeryHidden 

    'Return focus to the main page 
    ThisWorkbook.Worksheets(1).Activate 

    'Turn on Screen Updating 
    Application.ScreenUpdating = True 

    ThisWorkbook.Saved = True 

End Sub 

Private Sub Workbook_Open() 

    'Turn off Screen Updating 
    Application.ScreenUpdating = False 

    'Show all sheets 
    For Each sh In ThisWorkbook.Worksheets 
     sh.Visible = xlSheetVisible 
    Next sh 

    'Hide the warning sheet 
    Sheets("Warning").Visible = xlVeryHidden 

    'Return focus to the main page 
    ThisWorkbook.Worksheets(1).Activate 

    'Turn on Screen Updating 
    Application.ScreenUpdating = True 

    ThisWorkbook.Saved = True 

End Sub 

और बस संपूर्णता के लिए है, यहाँ मद दस्तावेज़

'Declarations 
'Strings 
Public strSourceFolder As String 
Public strTextFile As String 

'Other 
Public fso As FileSystemObject 
Public booChange As Boolean 
Public wsFlow As Worksheet 

'Constants 
Public Const strURNSheetName = "Part 1 Plant Flow Out Summ" 

Sub Auto_Open() 

    Set fso = CreateObject("Scripting.FileSystemObject") 
    Set wsFlow = ThisWorkbook.Worksheets(strURNSheetName) 
    strSourceFolder = fso.Getfile(ThisWorkbook.FullName).ParentFolder.Path 
    strTextFile = fso.BuildPath(strSourceFolder, ThisWorkbook.Worksheets(strURNSheetName).Range("W2").Value & ".txt") 

End Sub 

की Module1 में सभी कोड जब एक आइटम मास्टर में बनाया जाता है 'FrmNewEntry' फॉर्म का उपयोग कर दस्तावेज़ को चेक किया गया है और मास्टर दस्तावेज़ में प्रवेश किया गया है, फिर एक टेम्पलेट आइटम दस्तावेज़ खोला गया है और एक नए अद्वितीय फ़ाइल नाम से सहेजा गया है। यह तब असुरक्षित है, नई जानकारी, संरक्षित, सहेजा और बंद के साथ अद्यतन किया गया है। मास्टर दस्तावेज़ तब सहेजा जाता है।

पर्चा कोड::

Private Sub btnSave_Click() 
    'Values on form are verified 
    'Master Document sheet is unprotected, formatted and data entry occurs 

    'Clear Userform and close 
    For Each C In frmNewEntry.Controls 
     If TypeOf C Is MSForms.ComboBox Then 
      C.ListIndex = -1 
     ElseIf TypeOf C Is MSForms.TextBox Then 
      C.Text = "" 
     ElseIf TypeOf C Is MSForms.CheckBox Then 
      C.Value = False 
     End If 
    Next 
    frmNewEntry.Hide 

    'Create filepaths 
    Create_Filepath 

    'Some hyperlinks are added and the Master Document worksheet is protected again 

    'Create Flowout Summary 
    Create_Flowout_Summary 

    'Update Flowout Summary 
    Update_Flowout_Summary 

    'Turn on screen updating 
    Application.ScreenUpdating = True 

    'Update Activity Log 
    Update_Log ("New: " & strNewURN) 

    Debug.Print "Before Save Master" 

    'Save tracker 
    ThisWorkbook.Save 

    Debug.Print "After Save Master" 

End Sub 

Module1 कोड:

Public Sub Create_Flowout_Summary() 
'Create a new flowout summary from the template 

    'Turn off screen updating 
    Application.ScreenUpdating = False 

    'Check if workbook is already open 
    If Not Is_Book_Open(strTemplate) Then 
     Application.Workbooks.Open (strTemplatePath) 
    End If 

    Debug.Print "Before SaveAs Create" 

    'Save as new flowout summary 
    Application.Workbooks(strTemplate).SaveAs fileName:=strFilePath 

    Debug.Print "After SaveAs Create" 

    'Close Document Information Panel 
    ActiveWorkbook.Application.DisplayDocumentInformationPanel = False 'Doesn't seem to work 

    'Turn on screen updating 
    Application.ScreenUpdating = True 

End Sub 

Public Sub Update_Flowout_Summary() 
'Update the flowout summary for current call 

    Dim wsURN As Worksheet 

    Set wsURN = Workbooks(strFileName).Worksheets(strWsURNName) 

    'Unprotect Flowout Summary worksheet 
    wsURN.Unprotect "Flowout Summary" 

    'Write values to flowout summary 

    'Protect Flowout Summary worksheet 
    wsURN.Protect "Flowout Summary", False, True, True, True, True 

    Debug.Print "Before Save Update" 

    'Save flowout summary 
    Application.Workbooks(strFileName).Save 

    Debug.Print "After Save Update" 

    'Close Document Information Panel 
    ActiveWorkbook.Application.DisplayDocumentInformationPanel = False 

    'Turn on screen updating 
    Application.ScreenUpdating = True 

End Sub 

समस्या विस्तार: जब मैं एक नई प्रविष्टि बनाने यह ले जा रहा है संहिता (लंबा स्वरूपण और डेटा प्रविष्टि छोड़ संपादित) इस प्रकार बहुत लंबा समय, मैंने गलती से पाया कि मास्टर दस्तावेज़ प्रत्येक शीट सक्रिय घटना (ऊपर उल्लिखित) में कोड चला रहा है (मेरे पास एक शीट में डायग्नोस्टिक संदेश था जो रहस्यमय रूप से दिखाई देता था जब मैंने एक नई प्रविष्टि बनाई थी) मैंने इस निष्कर्ष को निष्कर्ष निकाला है कि कोड किसी भी तरह से प्रत्येक वर्कशीट को सक्रिय कर रहा है लेकिन मुझे नहीं पता कि क्यों ....

किसी भी मदद की बहुत सराहना की जाएगी, और यदि मुझे कुछ भी याद आया है जो मुझे निदान करने में मदद कर सकता है जानना।

संपादित करें: अन्य अजीब घटना यह है कि ऐसा तब नहीं होता जब मैं कोड को चरणबद्ध करने की कोशिश करता हूं ताकि सक्रिय घटनाओं को ट्रिगर किया जा सके।

संपादित करें: कार्यपत्रक में कोड घटना को सक्रिय

Private Sub Worksheet_Activate() 

    'Turn off Screen Updating 
    Application.ScreenUpdating = False 

    'Simply writes data to the sheet (excluded because it is lengthy) 

    'Turn on Screen Updating 
    Application.ScreenUpdating = True 

    wsMyCalls.Protect Password:=strPassword 

    Debug.Print "wsMyCalls" 

    MsgBox "This sheet uses your username to display any calls you own." & vbNewLine & _ 
    "It relies on the correct CDSID being entered for owner." & vbNewLine & vbNewLine & _ 
    "Regards" & vbNewLine & _ 
    "Your friendly spreadsheet administrator", vbOKOnly, "Information" 

End Sub 

संपादित करें: मैं कोड (ऊपर) के लिए कुछ Debug.Prints जोड़ा गया है और यह मैं क्या मिल गया है।

  • पहले SaveAs बनाएं
  • बाद SaveAs
  • बनाएं इससे पहले सहेजें अद्यतन
  • के बाद सहेजें अद्यतन
  • इससे पहले मास्टर सहेजें
  • मास्टर सहेजें
  • wsMyCalls बाद

यह दिखाता है कोड Debug.Print के बीच निष्पादित हो रहा है और एक End Sub "मास्टर को बचाने के बाद" है। वहां कोई कोड नहीं है ???

धन्यवाद

+1

आपको अपने कोड में कार्यपुस्तिका को सहेजने से पहले ईवेंट को अक्षम करने की आवश्यकता है। – Rory

+0

मैंने इसके बारे में सोचा लेकिन इसका मतलब यह होगा कि आइटम दस्तावेज़ को चेतावनी पत्र के बिना सहेजा गया है। मुझे घटनाओं को सक्रिय होने की आवश्यकता है। संपादित करें: यही कारण है कि मैंने आइटम दस्तावेज़ में वर्कशीट छिपाने और दिखाने के लिए लूप को यह वर्कशीट्स वर्कशीट्स जोड़ा। – Nervix

+0

फिर आपको अन्य चादरें छिपाने/दिखाने से पहले ईवेंट को अक्षम करने के लिए अन्य कोड को बदलने की आवश्यकता होगी और फिर ईवेंट को पुन: सक्षम करें। – Rory

उत्तर

1

मुझे विश्वास है कि हम यहां आपका पूरा कोड नहीं देख रहे हैं। यह मानना ​​मुश्किल है कि हमारे पास डीबग करने के लिए कार्यपुस्तिका नहीं है। हालांकि मैं एक ऐसी ही 'स्वागत' पृष्ठ है कि हर बार मेरी कार्यपुस्तिका में से एक macroes सक्रिय करने के लिए उपयोगकर्ता पूछने के लिए खुल जाता है दिखाया जाता है। मैं गलत पर EnableEvents रख दिया और बचत, और सहेजने के बाद इसे वापस रखने से पहले एक निश्चित राज्य में मेरी चादर डाल करते हैं।

मैं तुम्हें वास्तव में कैसे मैं यह कर, क्योंकि मैं एक महसूस कर रही आपकी समस्या को अक्षम करने के लिए नहीं EnableEvents सही समय हैं संबंधित है है दिखाएगा। मैं कैसे उल्लेख अधूरा कोड की वजह से कैसे अपनी कार्यपुस्तिका कार्यों के आधार पर यह समय के लिए अनिश्चित हूं।

चादर f_macros कहा जाता है।

मैं पहली बार में DisplayHeadings की वर्तमान स्थिति और इस तरह के रिकॉर्ड:

Dim Displaytabs As Boolean 
Dim DisplayHeadings As Boolean 
Dim menu As CommandBar 
Dim ligne As CommandBarControl 

Displaytabs = ActiveWindow.DisplayWorkbookTabs 
DisplayHeadings = ActiveWindow.DisplayHeadings 

मैं तो मेरे कस्टम रीसेट

Private Sub Worksheet_Activate() 
    ActiveWindow.DisplayHeadings = False 
    ActiveWindow.DisplayWorkbookTabs = False 
End Sub 

मेरी Workbook_BeforeSave में: यहाँ यह कार्यपत्रक सक्रिय घटना में है कि आगे नेविगेशन से बचाता है है राइट क्लिक करें, सक्षम एवेन्ट्स और स्क्रीन अपडेटिंग बंद करें। मैंने अच्छे उपाय के लिए DisplayWorkbookTabs को झूठी पर सेट किया है।

Application.ScreenUpdating = False 
Application.EnableEvents = False 
Application.CommandBars("Cell").reset 
ActiveWindow.DisplayWorkbookTabs = False 

तब मैं मैं बचाने के (एक और मॉड्यूल है कि नीचे संलग्न है में HideData, उप) Cacherdata चलाने के लिए, और मैं कार्यपुस्तिका उपयोगकर्ता को काम करने में वापस लाने के लिए उप macro_activees चलाते हैं। मैं EnableEvents वापस चालू करेंगे, और शीर्षकों वे कैसे थे करने के लिए वापस रख:

m_protection.Cacherdata 
ThisWorkbook.Save 
m_protection.macro_activees 

Application.ScreenUpdating = True 
Application.enableevents = True 
ActiveWindow.DisplayWorkbookTabs = Displaytabs 
ActiveWindow.DisplayHeadings = DisplayHeadings 

मैं साधारण सहेजें (! महत्वपूर्ण) रद्द करने और संकेत मिलता है कार्यपुस्तिका सहेजा जाता है तो वे सहेजने को कहा जा रहा है बिना सामान्य रूप से बाहर निकल सकते हैं।

Cancel = True 
ThisWorkbook.Saved = True 

पहले क्लोज़ में, यह जांचता है कि कार्यपुस्तिका स्थिति सहेजी गई है या नहीं। यदि हां, तो यह निकलता है। यदि नहीं, तो यह एक ऐसी ही प्रक्रिया करता है:

If Not (ThisWorkbook.Saved) Then 


     rep = MsgBox(Prompt:="Save changes before exiting?", _ 
      Title:="---", _ 
      Buttons:=vbYesNoCancel) 

    Select Case rep 
     Case vbYes 
      Application.ScreenUpdating = False 
      Application.enableevents = False 
      ActiveWindow.DisplayHeadings = True 
      m_protection.Cacherdata 

      ThisWorkbook.Save 

     Case vbCancel 
      Cancel = True 
      Exit Sub 
    End Select 
End If 

कार्यपुस्तिका खुली घटना जाँच करता है कि यह केवल पढ़ने के लिए मोड में है, लेकिन इतना ही है। मेरे पास वर्कबुक आफ्टरसेव नहीं है।

अनुलग्नक

CacherData हर शीट VeryHidden तो उपयोगकर्ता मैक्रो सक्रिय किए बिना f नहीं है *** अप डेटा बनाता है। यह वर्तमान सक्रिय पत्रक रिकॉर्ड तो उपयोगकर्ता वापस वे कहाँ थे करने के लिए चला जाता है, कार्यपुस्तिका unprotects, चादरें छुपाता है, इसे वापस रक्षा करता है और बस इतना ही है:

Sub Cacherdata() 
    Dim ws As Worksheet 

    f_param.Range("page_active") = ActiveSheet.Name 
    f_macros.Activate 


    ThisWorkbook.Unprotect "-----" 

    For Each ws In ThisWorkbook.Worksheets 
     If ws.CodeName <> "f_macros" Then ws.visible = xlSheetVeryHidden 
    Next 
    ThisWorkbook.Protect "-----" 

    Exit Sub 

End Sub 

macros_activees करता विपरीत:

Sub macro_activees() 
    Dim ws As Worksheet 


    ThisWorkbook.Unprotect "-----" 
    For Each ws In ThisWorkbook.Worksheets 
     ws.visible = xlSheetVisible 
    Next 
    ThisWorkbook.Sheets(f_param.Range("page_active").Value).Activate 
    ThisWorkbook.Unprotect "-----" 
'it unportects twice because of the activate event of the worksheet, don't mind that 
    Exit Sub 
End Sub 

त्रुटि हैंडलिंग हटा दी गई थी क्योंकि यह दिखाने के लिए बेकार था, लेकिन बाकी सब कुछ होना चाहिए।

संपादित करें: यदि यह आपकी मदद नहीं करता है, तो शायद आपकी समस्या यह है क्योंकि आपके द्वारा बनाई गई कार्यपुस्तिकाओं में 9 कोड जो मैं इकट्ठा करता हूं) जो आपके कोड को चलाने में कितना समय लगता है? अगर उनके पास एक ओपन प्रक्रिया है, तो क्या यह हो सकता है?

+0

आप कार्यपुस्तिका में सभी कोड नहीं देख रहे हैं। हालांकि, मैंने छोड़ा गया कोई भी कोड निष्पादित नहीं करता है या मैंने समझाया है कि यह क्यों गुम है। (उदाहरण के लिए मुख्य कार्यपुस्तिका के मूल्यों का लेखन क्योंकि यह लंबा और असंबंधित है) जो आप एकत्र कर सकते हैं, उसके लिए मुझे समझाने के लिए कोई बेहतर तरीका नहीं है। मैंने टेम्पलेट/आइटम दस्तावेजों (जो मैं बनाते हैं) में कार्यपुस्तिका ओपन इवेंट से कोड शामिल किया है ऊपर देखें। – Nervix

संबंधित मुद्दे