طريقة تشغيل وحدات ماكرو Excel من سطر الأوامر أو الملف الدفعي؟

StackOverflow https://stackoverflow.com/questions/2050505

سؤال

لدي ماكرو Excel VBA الذي أحتاج إلى تشغيله عند الوصول إلى الملف من ملف دفعي، ولكن ليس في كل مرة أفتحه (وبالتالي لا أستخدم حدث الملف المفتوح).هل هناك طريقة لتشغيل الماكرو من سطر الأوامر أو الملف الدفعي؟أنا لست على دراية بمثل هذا الأمر.

تفترض بيئة Windows NT.

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

المحلول

يمكنك تشغيل برنامج Excel وفتح المصنف وتشغيل الماكرو من ملف VBScript.

انسخ الكود أدناه في المفكرة.

تحديث "MyWorkbook.xls' و 'مايماكرو' حدود.

احفظه بامتداد vbs وقم بتشغيله.

Option Explicit

On Error Resume Next

ExcelMacroExample

Sub ExcelMacroExample() 

  Dim xlApp 
  Dim xlBook 

  Set xlApp = CreateObject("Excel.Application") 
  Set xlBook = xlApp.Workbooks.Open("C:\MyWorkbook.xls", 0, True) 
  xlApp.Run "MyMacro"
  xlApp.Quit 

  Set xlBook = Nothing 
  Set xlApp = Nothing 

End Sub 

الخط الرئيسي الذي يقوم بتشغيل الماكرو هو:

xlApp.تشغيل "MyMacro"

نصائح أخرى

وأبسط طريقة للقيام بذلك هي:

1) بدء تشغيل Excel من الملف الدفعي لفتح المصنف الذي يحتوي الماكرو الخاص بك:

EXCEL.EXE /e "c:\YourWorkbook.xls"

2) دعوة الماكرو من الحدث Workbook_Open المصنف، مثل:

Private Sub Workbook_Open()
    Call MyMacro1          ' Call your macro
    ActiveWorkbook.Save    ' Save the current workbook, bypassing the prompt
    Application.Quit       ' Quit Excel
End Sub

وهذا سوف يعود الآن للسيطرة على الملف الدفعي للقيام معالجة أخرى.

وأسلوب هو مبين أدناه يسمح لتشغيل محددة ماكرو Excel من ملف دفعي، فإنه يستخدم متغير البيئة لتمرير اسم الماكرو من دفعة إلى Excel.

ووضع هذا الرمز إلى ملف دفعي (استخدام مسارات لEXCEL.EXE والمصنف):

Set MacroName=MyMacro
"C:\Program Files\Microsoft Office\Office15\EXCEL.EXE" "C:\MyWorkbook.xlsm"

ووضع هذا الرمز إلى كائن اكسل VBA ThisWorkBook:

Private Sub Workbook_Open()
    Dim strMacroName As String
    strMacroName = CreateObject("WScript.Shell").Environment("process").Item("MacroName")
    If strMacroName <> "" Then Run strMacroName
End Sub

ووضع التعليمات البرمجية إلى Excel VBA وحدة، مثل ما يلي:

Sub MyMacro()
    MsgBox "MyMacro is running..."
End Sub

وإطلاق الملف الدفعي والحصول على النتيجة:

لالحال عندما كنت لا تنوي تشغيل أي ماكرو وضعت للتو Set MacroName= القيمة فارغة إلى دفعة واحدة.

هل يمكن إرسال بريد VBScript لإنشاء مثيل من التفوق عبر أسلوب CreateObject ()، ثم قم بفتح المصنف وتشغيل الماكرو. هل يمكن إما استدعاء فبسكريبت مباشرة، أو استدعاء VBScript من ملف دفعة واحدة.

وهنا هو مورد أنا فقط تعثرت تزوجنا: http://www.codeguru.com/forum/showthread.php؟t= 376401

ولقد اختبرت دائما عدد المصنفات المفتوحة في Workbook_Open (). إذا كان 1، ثم افتتح المصنف من سطر الأوامر (أو المستخدم إغلاق كافة المصنفات، ثم افتتح هذا واحد).

If Workbooks.Count = 1 Then

    ' execute the macro or call another procedure - I always do the latter  
    PublishReport

    ThisWorkbook.Save

    Application.Quit

End If

إذا كنت تعمل أكثر راحة داخل اكسل / VBA، استخدم الحدث مفتوح واختبار البيئة: إما أن يكون ملف إشارة، إدخال التسجيل أو متغير البيئة أن الضوابط ما حدث مفتوحة يفعل

يمكنك إنشاء ملف / إعداد خارج وداخل اختبار (استخدام GetEnviromentVariable للفار الحياة الفطرية) والاختبار بسهولة. لقد كتب فبسكريبت لكن أوجه التشابه مع VBA سبب لي المزيد من القلق من سهولة ..

[المزيد]

وكما فهمت المشكلة، وتريد استخدام جداول البيانات عادة أكثر / لبعض الوقت بعد أن يكون تشغيله في دفعة والقيام بشيء خارج / مختلف. يمكنك فتح ورقة من سطر الأوامر EXCEL.EXE ولكن لا يمكنك السيطرة على ما تقوم به ما لم يعرف أين هو. باستخدام متغير بيئة بسيطة نسبيا، ويجعل اختبار جدول سهلة.

لتوضيح، واستخدام وظيفة أدناه لدراسة البيئة. وفي تعلن وحدة نمطية:

Private Declare Function GetEnvVar Lib "kernel32" Alias "GetEnvironmentVariableA" _
    (ByVal lpName As String, ByVal lpBuffer As String, ByVal nSize As Long) As Long

Function GetEnvironmentVariable(var As String) As String
Dim numChars As Long

    GetEnvironmentVariable = String(255, " ")

    numChars = GetEnvVar(var, GetEnvironmentVariable, 255)

End Function

في حالة مصنف مفتوح (كما فعل آخرون):

Private Sub Workbook_Open()
    If GetEnvironmentVariable("InBatch") = "TRUE" Then
        Debug.Print "Batch"
    Else
        Debug.Print "Normal"
    End If
End Sub

وإضافة في كود نشاطا حسب مقتضى الحال. في الملف الدفعي، استخدام

set InBatch=TRUE

وبدلا من مقارنة مباشرة السلاسل (VB لن تجد لها يساوي منذ GetEnvironmentVariable بإرجاع سلسلة من طول 255) أكتب هذا:

Private Sub Workbook_Open()     
    If InStr(1, GetEnvironmentVariable("InBatch"), "TRUE", vbTextCompare) Then
        Debug.Print "Batch"  
        Call Macro
    Else    
        Debug.Print "Normal"     
    End If 

End Sub 

@ روبرت:لقد حاولت تكييف التعليمات البرمجية الخاصة بك مع مسار نسبي، وقمت بإنشاء ملف دفعي لتشغيل VBS.

يبدأ تشغيل VBS ويغلق ولكنه لا يقوم بتشغيل الماكرو...هل لديك أي فكرة عن المكان الذي يمكن أن تكون فيه المشكلة؟

Option Explicit

On Error Resume Next

ExcelMacroExample

Sub ExcelMacroExample() 

  Dim xlApp 
  Dim xlBook 

  Set xlApp = CreateObject("Excel.Application")
  Set objFSO = CreateObject("Scripting.FileSystemObject")
  strFilePath = objFSO.GetAbsolutePathName(".") 
  Set xlBook = xlApp.Workbooks.Open(strFilePath, "Excels\CLIENTES.xlsb") , 0, True) 
  xlApp.Run "open_form"


  Set xlBook = Nothing 
  Set xlApp = Nothing 

End Sub

لقد قمت بإزالة "Application.Quit" لأن الماكرو الخاص بي يتصل بنموذج مستخدم يعتني به.

هتافات

يحرر

لقد قمت بالفعل بحل هذه المشكلة، فقط في حالة رغبة شخص ما في تشغيل نموذج مستخدم "على حد سواء" كتطبيق مستقل:

المشكلات التي كنت أواجهها:

1 - لم أرغب في استخدام حدث Workbook_Open لأن برنامج Excel مقفل للقراءة فقط.2 - الأمر الدفعي يقتصر على حقيقة أنه (على حد علمي) لا يمكنه استدعاء الماكرو.

لقد قمت أولاً بكتابة ماكرو لتشغيل نموذج المستخدم الخاص بي أثناء إخفاء التطبيق:

Sub open_form()
 Application.Visible = False
 frmAddClient.Show vbModeless
End Sub

قمت بعد ذلك بإنشاء vbs لتشغيل هذا الماكرو (كان القيام بذلك باستخدام مسار نسبي أمرًا صعبًا):

dim fso
dim curDir
dim WinScriptHost
set fso = CreateObject("Scripting.FileSystemObject")
curDir = fso.GetAbsolutePathName(".")
set fso = nothing

Set xlObj = CreateObject("Excel.application")
xlObj.Workbooks.Open curDir & "\Excels\CLIENTES.xlsb"
xlObj.Run "open_form"

وأخيراً قمت بعمل ملف دفعي لتنفيذ VBS ...

@echo off
pushd %~dp0
cscript Add_Client.vbs

لاحظ أنني قمت أيضًا بتضمين "الرجوع إلى المرئي" في ملفي Userform_QueryClose:

Private Sub cmdClose_Click()
Unload Me
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    ThisWorkbook.Close SaveChanges:=True
    Application.Visible = True
    Application.Quit
End Sub

على أية حال، شكرًا لمساعدتك، وآمل أن يكون هذا مفيدًا إذا احتاجه شخص ما

ويمكنك معرفة ما اذا كان اكسل مفتوح مسبقا. ليست هناك حاجة لخلق isntance آخر

   If CheckAppOpen("excel.application")  Then
           'MsgBox "App Loaded"
            Set xlApp = GetObject(, "excel.Application")   
   Else
            ' MsgBox "App Not Loaded"
            Set  wrdApp = CreateObject(,"excel.Application")   
   End If

وأنا جزئي إلى C #. ركضت باستخدام linqpad التالية. ولكن يمكن بسهولة مثلما يتم تجميعها مع ديوان الخدمة المدنية وركض من خلال استدعاء من سطر الأوامر.

لا تنس أن تضيف حزم تتفوق على مساحة الاسم.

void Main()
{
    var oExcelApp = (Microsoft.Office.Interop.Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
    try{
        var WB = oExcelApp.ActiveWorkbook;
        var WS = (Worksheet)WB.ActiveSheet;
        ((string)((Range)WS.Cells[1,1]).Value).Dump("Cell Value"); //cel A1 val
        oExcelApp.Run("test_macro_name").Dump("macro");
    }
    finally{
        if(oExcelApp != null)
            System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcelApp);
        oExcelApp = null;
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top