سؤال

لدي رمز يحتاج إلى تشغيله على كلا Excel 2003 و Excel 2007، وهناك بعض النقاط التي تتسبب فيها التغييرات في الإصدارات في وقف التعليمات البرمجية. حاولت فصل هذه الخطوط مع العبارات If-Erets، لكن الرمز لن يترجم عليه إما لأنه لا يتعرف على الكود المستخدم للآخر. هل هناك أي طريقة يمكنني أن أقول نسخة واحدة لتجاهل كتلة من التعليمات البرمجية، على غرار نمط C أو C ++ #IFDEF، في VBA؟

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

المحلول

هذه نقطة انطلاق جيدة، لكنها لن تعمل مع إصدار Excel الذي يعمل عليه، لأنه لا يمكن اعتباره فقط في وقت التشغيل، وليس تجميع الوقت.

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

يمكن استخدام الطريقة الأولى إذا كنت بحاجة إلى الوصول إلى خاصية أو طريقة موجودة فقط في إصدارات معينة، يمكنك استخدام CallByName. ميزة الاتصال بالاسم هي أنه يسمح لك بالحفاظ على الربط المبكر (والثانية الجنسية) لكائناتك قدر الإمكان.

لإعطاء مثال، يحتوي Excel 2007 على خاصية Tintandshade جديدة. إذا كنت ترغب في تغيير لون النطاق، وبالنسبة ل Excel 2007، ضمان تعيين Tintandshade على 0، وسوف تواجه مشكلة لأن الرمز لن يترجم في Excel 2003 الذي لا يحتوي على Tintandshade كخاصية لكائن النطاق. إذا قمت بالوصول إلى العقار الذي تعرفه أنه ليس في جميع الإصدارات باستخدام CallByName، فسوف يترجم رمزك في جميع الإصدارات بشكل جيد، ولكن يتم تشغيله فقط في الإصدارات التي تحددها. انظر أدناه:

Sub Test() 
    ColorRange Selection, Excel.Application.version, 6 
End Sub 
Sub ColorRange(rng As Excel.Range, version As Double, ParamArray args() As Variant) 
    With rng.Interior 
        .colorIndex = 6 
        .Pattern = xlSolid 
        If version >= 12# Then 
             'Because the property name is stored in a string this will still compile.
             'And it will only get called if the correct version is in use.
            CallByName rng.Interior, "TintAndShade", VbLet, 0 
        End If 
    End With 
End Sub 

الطريقة الثانية هي للفئات التي يجب إنشاء مثيل لها عبر "جديد" ولا توجد حتى في الإصدارات القديمة. لن تواجه هذه المشكلة مع Excel، لكنني سأقدم عرضا تجريبي سريع حتى تتمكن من رؤية ما أعنيه:

تخيل أنك تريد أن تقوم بملف IO، وبعض السبب الغريب ليس كل أجهزة الكمبيوتر التي تحتوي على وقت تشغيل Microsoft Scripting عليها. ولكن بالنسبة لبعض السبب الغريب بنفس القدر تريد أن تتأكد من استخدامها كلما كان ذلك متاحا. إذا قمت بتعيين مرجع عليه واستخدام الربط المبكر في التعليمات البرمجية الخاصة بك، فلن يترجم الكود على الأنظمة التي لا تملك الملف. لذلك تستخدم الربط المتأخر بدلا من ذلك:

Public Sub test()
    Dim strMyString As String
    Dim strMyPath As String
    strMyPath = "C:\Test\Junk.txt"
    strMyString = "Foo"
    If LenB(Dir("C:\Windows\System32\scrrun.dll")) Then
        WriteString strMyPath, strMyString
    Else
        WriteStringNative strMyPath, strMyString
    End If
End Sub

Public Sub WriteString(ByVal path As String, ByVal value As String)
    Dim fso As Object '<-Use generic object
    'This is late binding:
    Set fso = CreateObject("Scripting.FileSystemObject")
    fso.CreateTextFile(path, True, False).Write value
End Sub

Public Sub WriteStringNative(ByVal path As String, ByVal value As String)
    Dim lngFileNum As Long
    lngFileNum = FreeFile
    If LenB(Dir(path)) Then Kill path
    Open path For Binary Access Write Lock Read Write As #lngFileNum
    Put #lngFileNum, , value
    Close #lngFileNum
End Sub

هناك قائمة شاملة بجميع الزيادات والتغييرات في نموذج كائن Excel منذ عام 2003:
http://msdn.microsoft.com/en-us/library/bb149069.aspx.للتغييرات بين عامي 1997 و 2000 تذهب هنا:
http://msdn.microsoft.com/en-us/library/aa140068(office.10).aspx.

نصائح أخرى

نعم، من الممكن القيام بتجميع مشروط في Excel VBA. فيما يلي مورد مختصر وبعض رمز المثال:تجميع مشروط

#If Win32 Then
    ' Profile String functions:
    Private Declare Function WritePrivateProfileString Lib "KERNEL32" Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName As String) As Long
    Private Declare Function GetPrivateProfileString Lib "KERNEL32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As Any, ByVal lpKeyName As Any, ByVal lpDefault As Any, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long
#Else
    ' Profile String functions:
    Private Declare Function WritePrivateProfileString Lib "Kernel" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpString As Any, ByVal lpFileName As String) As Integer
    Private Declare Function GetPrivateProfileString Lib "Kernel" (ByVal lpApplicationName As String, ByVal lpKeyName As Any, ByVal lpDefault As Any, ByVal lpReturnedString As String, ByVal nSize As Integer, ByVal lpFileName As String) As Integer
#End If

يمكنك نشر خطوط المخالف للرمز؟

إذا كان الأمر ثابتا مثل VBYES أو XLFileFormat أو أيا كان، فاستخدم القيمة الرقمية المقابلة.

أرني ما حصلت عليه، سأرى ما إذا كان بإمكاني إعادة تكوينه.

مشروع قانون

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