python - एक्स्ट्रा स्प्रेडशीट पायथन का उपयोग करने के लिए लिंक अपडेट करें



हिंदी में स्प्रेडशीट के फायदे (1)

Python को सीधे सीडी ऑब्जेक्ट्स के साथ अपडेट लिंक्ड को चलाने के बारे में सोचें , अर्थात् xl_app और wb ऑब्जेक्ट्स। प्रत्येक कार्यपुस्तिका में मैक्रो बनाने की ज़रूरत नहीं है और फिर इसे कॉल करें।

UpdateLink() नीचे एक try/except/finally ब्लॉक में लपेटा जाता है, क्योंकि कार्यपुस्तिका के पास कोई लिंक नहीं है क्योंकि LinkSources खाली मूल्य लौटाएंगे , एक COM अपवाद उठाएंगे , आपको बहुत त्रुटि मिलेगी:

ऑब्जेक्ट '_वर्कबुक' की रन-टाइम एरर '1004' विधि 'अपडैटिलिंक' विधि विफल रही

इसके अलावा वस्तुओं को खोलने के लिए सुनिश्चित करें (वीबीए में एक अच्छा सर्वोत्तम अभ्यास भी: Set wb = Nothing ) सीपीयू संसाधनों को मुक्त करने के लिए उपयोग करने के बाद वे कचरा संग्रह तक पृष्ठभूमि प्रक्रिया के रूप में बने रहते हैं।

def run_macro(workbook_name, com_instance):
    wb = com_instance.workbooks.open(workbook_name)
    com_instance.AskToUpdateLinks = False
    try:
       wb.UpdateLink(Name=wb.LinkSources())

    except Exception as e:
       print(e)

   finally:
       wb.Close(True)
       wb = None    
    return True

def main():
    dir_root  = ("C:\\Model_Spreadsheets")

    xl_app = Dispatch("Excel.Application")
    xl_app.Visible = False
    xl_app.DisplayAlerts = False

    for root, dirs, files in os.walk(dir_root):
        for fn in files:
            if fn.endswith(".xlsx") and fn[0] is not "~":
                run_macro(os.path.join(root, fn), xl_app)
    xl_app.Quit()
    xl = None

एक तरफ - हालांकि, एक्सेल और एमएस ऑफिस एप्लिकेशंस के जरिए डिप्टी डिफॉल्ट के तौर पर वीबीए जहाजों का एक अलग घटक है। VBA आईडीई में टूल्स \ रेफ़रेंस के तहत जांचने के लिए, आप देखेंगे कि वीबीए पहला चेक किया गया आइटम है, इसमें कुछ भी नहीं है। वास्तव में, VBA ठीक उसी प्रकार से करता है जो आप पायथन में कर रहे हैं: Excel ऑब्जेक्ट लाइब्रेरी के लिए एक COM इंटरफ़ेस बना रहा है। तो एक अर्थ में VBA बस एक्सेल और पायथन से संबंधित है!

मैं पायथन में सिम्युलेशन चला रहा हूं जो उत्पादन को उत्पन्न करता है, जिसकी ज़रूरत उनके उत्कृष्ट कार्यपुस्तिकाओं में एक मॉडलर द्वारा सीधे खपत करने की आवश्यकता होती है। मैंने कोड जेनरेट किया है जो सीधे अपने डेटा को अपने एक्सेल स्प्रैडशीट टेम्पलेट में प्रदर्शित करेगा I मैंने अपने डेटा को सीधे उनके टेम्पलेट पर आउटपुट करने के लिए तैयार कोड को ठीक किया है, लेकिन जो समस्या मैं चल रही हूं वह यह है कि मॉडेलर में कार्यपुस्तिकाओं की एक श्रृंखला होती है जो एक साथ "लिंक" होती हैं। यदि मैं अपना डेटा अपनी स्प्रेडशीट में डालता हूं, तो उस कार्यपुस्तिका के लिंक कोई अद्यतन नहीं करते हैं, जब तक कि उपयोगकर्ता शारीरिक रूप से "लिंक संपादित करें" -> "अपडेट मान" को कार्यपुस्तिका खोलता है। अगर एक कार्यपुस्तिका थी, तो उपयोगकर्ता बिना किसी समस्या के कार्यपुस्तिका खोल सकता है। हकीकत में, 100 से अधिक कार्यपुस्तिकाएं होंगी, जिनकी ज़रूरतें लिंक को अपडेट करनी होंगी। दुर्भाग्यवश, कार्यपुस्तिकाओं को जोड़ने में मॉडेल के दृष्टिकोण को बदलने के लिए मैं कुछ भी नहीं कर सकता- केवल एक चीज जो मैं कर सकती हूं वह उनके दृष्टिकोण को समायोजित करती है।

मेरा लक्ष्य एक पायथन समाधान बनाना है जो मुझे 1) सिम्युलेटेड डेटा जेनरेट करने की अनुमति देगा, 2) मेरे उत्पन्न डेटा को मॉडलर की कार्यपुस्तिका में डालें, और 3) कार्यपुस्तिकाओं के बीच सभी लिंक अपडेट करें अंत में, सुव्यवस्थित होने के लिए, मैं एक तिहाई से अंत पायथन प्रोग्राम में सभी तीनों को करने में सक्षम होना चाहता हूं। मैंने (1) और (2) हल किया है, और मेरे पास एक समाधान है (3) जो लगभग काम करता है मैंने निम्न कार्यात्मक स्क्रिप्ट उत्पन्न की है:

from win32com.client import Dispatch
import pandas as pd
from openpyxl import load_workbook
import os
import time

def run_macro(workbook_name, vba_sub, com_instance):
    wb = com_instance.workbooks.open(workbook_name)
    wb.RefreshAll()
    xl_module = wb.VBProject.VBComponents.Add(1)
    xl_module.CodeModule.AddFromString(vba_sub.strip())
    com_instance.Application.Run('UpdateLinkValues')
    wb.Save()
    wb.Close()

    return True

def main():
    dir_root  = ("C:\\Model_Spreadsheets")

    vba_sub = \
        '''
        sub UpdateLinkValues()
            Application.AskToUpdateLinks = False
            ActiveWorkbook.UpdateLink Name:=ActiveWorkbook.LinkSources
        end sub
        '''

    xl_app = Dispatch("Excel.Application")
    xl_app.Visible = False
    xl_app.DisplayAlerts = False

    for root, dirs, files in os.walk(dir_root):
        for fn in files:
            if fn.endswith(".xlsx") and fn[0] is not "~":
                run_macro(os.path.join(root, fn), vba_sub, xl_app)
    xl_app.Quit()


if __name__ == "__main__":
    main()

यह स्क्रिप्ट वास्तव में सही समाधान के करीब है जो मैं देख रहा हूं, लेकिन मुझे लगता है कि 'बेतरतीब ढंग से' एक VBA त्रुटि में चलाया जाता है:

run-time error '1004' method 'updatelink' method of object '_workbook' failed

यह त्रुटि हर बार जब मैं इस स्क्रिप्ट को चलाने की कोशिश करता हूं, लेकिन हर बार एक ही कार्यपुस्तिका के लिए ऐसा नहीं होता है - कभी-कभी, यह पहली कार्यपुस्तिका पर होता है, कभी-कभी 15 वीं, आदि पर ...

मेरे पास VBA में डिबग करने का एक विकल्प है, और एकमात्र तरीका है कि मैं अगले कार्यपुस्तिका पर जारी रख सकता हूं अगर मैं मैक्रो को बदलता हूं

sub UpdateLinkValues()
    Application.AskToUpdateLinks = False
end sub

अगर मैं इस मैक्रो को चलाता हूं और डिबग से बाहर निकलता हूं, तब तक कार्यक्रम तब तक चलता रहेगा जब तक कि इसे उसी त्रुटि का सामना न करें। मेरा पहला सोचा था कि मेरे बीच कार्यपुस्तिका खोलने और मैक्रो चलाने की कोशिश करते समय शायद एक समय का मुद्दा हो। मैंने पाया है कि एक वैकल्पिक हल यह है कि मैं मैक्रो और ऐप दृश्यता बदल सकता हूँ:

vba_sub = \
    '''
    sub UpdateLinkValues()
        Application.AskToUpdateLinks = False
    end sub
    '''

तथा

xl_app.Visible = True

यह ठीक काम करता है, लेकिन मैं प्रत्येक कार्यपुस्तिका खोलने और बंद करने के प्रशंसक नहीं हूं क्योंकि इसमें बहुत समय लगता है। मेरा प्रश्न यह है, क्या किसी को पता है कि एक हल से यह रन-टाइम त्रुटि क्यों आ रही है? या शायद, क्या किसी को यह पता है कि पायथन में इस रन-टाइम त्रुटि को एक अपवाद के रूप में कैसे अवरुद्ध करना है? अगर मैं अजगर में एक अपवाद के रूप में इस त्रुटि को अवरुद्ध कर सकता हूं, तो मैं उन वैकल्पिक कार्यपुस्तिकाओं के लिए अपने वैकल्पिक समाधान का उपयोग कर सकता हूं

अग्रिम में धन्यवाद!





macros