Yair دارای دو ماکرو در یک کتاب کار است: یک UDF و یک برنامه فرعی که (از جمله موارد دیگر) یک کاربرگ را به کتاب کار اضافه می کند. به نظر می رسد که او نمی تواند زیربرنامه را از داخل UDF فراخوانی کند، بنابراین از خود می پرسد که آیا محدودیتی در مورد استفاده از CALL در یک UDF وجود دارد یا خیر. اگر وجود داشته باشد، او تعجب می کند که چرا، و اگر وجود ندارد، او تعجب می کند که برای فراخوانی زیربرنامه چه کاری می تواند انجام دهد.
شما می توانید در یک UDF (عملکرد تعریف شده توسط کاربر) از عبارت CALL استفاده کنید. VBA (و Excel) به شما این امکان را می دهد. کاری که نمی توانید در طول اجرای UDF یا یک برنامه فرعی که توسط UDF فراخوانی می شود انجام دهید، تغییر محیط اکسل است. این بدان معناست که شما نمی توانید اقدامی انجام دهید که ساختار کاربرگ یا ساختار کتاب کار را تغییر دهد. این همه نیست، هر چند. کارهای دیگری وجود دارد که نمی توان در حین اجرای UDF انجام داد. این موارد در این سایت مایکروسافت به تفصیل آمده است:
https://support.microsoft.com/en-us/topic/description-of-limitations-of-custom-functions-in-excel-f2f0ce5d-8ea5-6ce7-fddc-79d36192b7a1
توجه داشته باشید که این مقاله نشان میدهد که برای Excel 2010 قابل اجرا است، اگرچه برای سایر نسخههای مدرن اکسل نیز قابل اجرا است. همچنین توجه داشته باشید که دلیل اینکه UDF نمی تواند محیط اکسل را تغییر دهد این است که هدف آنها این نیست - آنها برای تقویت مجموعه توابع داخلی اکسل در نظر گرفته شده اند، که همچنین محیط اکسل را تغییر نمی دهند. توابع (ساخته شده یا تعریف شده توسط کاربر) برای برگرداندن مقادیر در نظر گرفته شده اند.
نکته اصلی در مورد Yairs این است که تابع CALL کاملاً خوب است، اما آنچه در طول تابع CALL انجام میشود (افزودن یک کاربرگ به کتاب کار) خوب نیست - اینجاست که قطع تماس است. بنابراین، چگونه می خواهید آنچه را که یایر می خواهد انجام دهید؟ من فکر می کنم بهترین راه بازسازی رابطه بین UDF و زیربرنامه خواهد بود. به عنوان مثال، میتوان گفت که زیربرنامه Yairs (یکی که در میان چیزهای دیگر، یک کاربرگ اضافه میکند) MyRoutine نامیده میشود. Yair می تواند آن زیربرنامه را به این ترتیب ساختار دهد:
Dim bFlag As Boolean
Sub MyRoutine()
define the variables and constants you want to use
If bFlag Then
add worksheet and do other things you cannot
do in the UDF
bFlag = False reset the flag to False
End If
do other things you need to do
reset the timer:
Application.OnTime Now() + TimeValue("00:01:00"), "MyRoutine"
End Sub
در این مثال، متغیر bFlag خارج از هر رویه ای تنظیم می شود، اما همچنان در ماژول است. به این ترتیب می توان به مقدار متغیر توسط تمام رویه های داخل ماژول دسترسی پیدا کرد.
در مرحله بعد، باید یک تایمر (با استفاده از روش OnTime) برای اجرای MyRoutine در نقطهای آینده تنظیم شود. اگر می خواهید تایمر را به صورت دستی تنظیم کنید، می توانید از یک ماکرو کوتاه مانند زیر استفاده کنید:
Sub SetTimer()
Application.OnTime Now() + TimeValue("00:01:00"), "MyRoutine"
End Sub
یا، میتوانید یک خط کد را به یک مدیریت رویداد، مانند Workbook_Open اضافه کنید تا زمانی که کتاب کار باز میشود، بهطور خودکار اجرا شود. پس از تنظیم تایمر، MyRoutine (در این مورد) هر دقیقه اجرا می شود. مقدار متغیر bFlag در زیر روال بررسی می شود و اگر True باشد، کارهایی که می خواستید در UDF انجام دهید اجرا می شوند.
تنها کاری که باید انجام دهید این است که این خط را به UDF خود اضافه کنید:
bFlag = True
پرچم Boolean تنظیم میشود و دفعه بعد که MyRoutine اجرا میشود، تغییرات مورد نظر را در Workbook خود دریافت خواهید کرد. و از آنجایی که تغییرات خارج از UDF رخ می دهد، هر دو VBA و Excel خوشحال هستند.