एक बहुत अच्छा diff गूगल यहाँ द्वारा की मेजबानी वर्ग नहीं है:मैं एक्सेल मैक्रो के भीतर जावास्क्रिप्ट का उपयोग कैसे कर सकता हूं?
http://code.google.com/p/google-diff-match-patch/
मैं इसे पहले का उपयोग किया है कुछ वेब साइटों पर, लेकिन अब मैं एक एक्सेल मैक्रो के भीतर यह उपयोग करने के लिए पाठ की तुलना करनी होती दो कोशिकाओं के बीच।
हालांकि, यह केवल जावास्क्रिप्ट, पायथन, जावा और सी ++ में उपलब्ध है, वीबीए नहीं।
मेरे उपयोगकर्ता Excel 2003 तक सीमित हैं, इसलिए एक शुद्ध .NET समाधान काम नहीं करेगा। कोड को वीबीए में मैन्युअल रूप से अनुवाद करने में बहुत अधिक समय लगेगा और अपग्रेड करना मुश्किल होगा।
एक विकल्प जिसे मैंने माना था, .NET कंपाइलर्स (JScript.NET या J #) का उपयोग कर जावास्क्रिप्ट या जावा स्रोत को संकलित करना था, VB.NET के रूप में आउटपुट करने के लिए परावर्तक का उपयोग करें, फिर आखिरकार VB.NET कोड को वीबीए में डाउनग्रेड करें, मुझे एक शुद्ध वीबीए समाधान दे रहा है। किसी भी .NET संकलक के साथ संकलित करने में समस्याएं होने के बाद, मैंने इस पथ को छोड़ दिया।
मान लीजिए कि मैं एक काम कर रहा था .NET लाइब्रेरी, मैं ExcelDna (http://www.codeplex.com/exceldna) का उपयोग भी कर सकता था, एक ओपन-सोर्स एक्सेल ऐड-इन, .NET कोड एकीकरण को आसान बनाने के लिए।
मेरा अंतिम विचार इंटरनेट एक्सप्लोरर ऑब्जेक्ट होस्ट करना था, इसे जावास्क्रिप्ट स्रोत भेजना और उसे कॉल करना था। यहां तक कि अगर मुझे यह काम करने के लिए मिला, तो मेरा अनुमान है कि यह गंदगी-धीमी और गन्दा होगी।
अद्यतन: समाधान मिला!
मैंने स्वीकार किए गए उत्तर से नीचे वर्णित WSC विधि का उपयोग किया। मैं डिफ साफ करने के लिए एक छोटे से और मुझे वापस दे सरणियों की एक VBA संगत सरणी WSC कोड बदलना पड़ा:
function DiffFast(text1, text2)
{
var d = dmp.diff_main(text1, text2, true);
dmp.diff_cleanupSemantic(d);
var dictionary = new ActiveXObject("Scripting.Dictionary"); // VBA-compatible array
for (var i = 0; i < d.length; i++) {
dictionary.add(i, JS2VBArray(d[i]));
}
return dictionary.Items();
}
function JS2VBArray(objJSArray)
{
var dictionary = new ActiveXObject("Scripting.Dictionary");
for (var i = 0; i < objJSArray.length; i++) {
dictionary.add(i, objJSArray[ i ]);
}
return dictionary.Items();
}
मैं WSC पंजीकृत है और यह ठीक काम किया। यह फोन करने के लिए VBA में कोड इस प्रकार है:
Public Function GetDiffs(ByVal s1 As String, ByVal s2 As String) As Variant()
Dim objWMIService As Object
Dim objDiff As Object
Set objWMIService = GetObject("winmgmts:")
Set objDiff = CreateObject("Google.DiffMatchPath.WSC")
GetDiffs = objDiff.DiffFast(s1, s2)
Set objDiff = Nothing
Set objWMIService = Nothing
End Function
(मैं एक ही वैश्विक objWMIService रखने की कोशिश की और objDiff तो चारों ओर मैं बना/प्रत्येक कक्ष के लिए इन नष्ट करने के लिए नहीं होगा, लेकिन यह नहीं मालूम था प्रदर्शन पर एक अंतर बनाने के लिए।)
मैंने फिर अपना मुख्य मैक्रो लिखा। इसमें तीन पैरामीटर होते हैं: मूल मानों की एक सीमा (एक कॉलम), नए मानों की एक श्रृंखला, और एक सीमा जहां भिन्नता को परिणामों को डंप करना चाहिए। सभी हैं पर समान संख्या में पंक्ति रखने के लिए, मुझे यहां कोई गंभीर त्रुटि-जांच नहीं चल रही है।
Public Sub DiffAndFormat(ByRef OriginalRange As Range, ByRef NewRange As Range, ByRef DeltaRange As Range)
Dim idiff As Long
Dim thisDiff() As Variant
Dim diffop As String
Dim difftext As String
difftext = ""
Dim diffs() As Variant
Dim OriginalValue As String
Dim NewValue As String
Dim DeltaCell As Range
Dim row As Integer
Dim CalcMode As Integer
ये अगले तीन लाइनों बाद में उपयोगकर्ता की पसंदीदा गणना मोड botching बिना अद्यतन में तेजी लाने के:
Application.ScreenUpdating = False
CalcMode = Application.Calculation
Application.Calculation = xlCalculationManual
For row = 1 To OriginalRange.Rows.Count
difftext = ""
OriginalValue = OriginalRange.Cells(row, 1).Value
NewValue = NewRange.Cells(row, 1).Value
Set DeltaCell = DeltaRange.Cells(row, 1)
If OriginalValue = "" And NewValue = "" Then
पिछले डिफ मिटाया जा रहा है, यदि कोई हो, के लिए महत्वपूर्ण है:
Erase diffs
यह परीक्षण मेरे उपयोगकर्ताओं के लिए एक दृश्य शॉर्टकट है, इसलिए जब कोई बदलाव नहीं होता है तो यह स्पष्ट होता है:
ElseIf OriginalValue = NewValue Then
difftext = "No change."
Erase diffs
Else
एक साथ सभी पाठ कम्बाइन डेल्टा सेल मूल्य के रूप में, चाहे पाठ समान था, डाला, या नष्ट कर दिया:
DeltaCell.value2 = difftext
Call FormatDiff(diffs, DeltaCell)
Next
Application.ScreenUpdating = True
Application.Calculation = CalcMode
End Sub
: diffs = GetDiffs(OriginalValue, NewValue)
For idiff = 0 To UBound(diffs)
thisDiff = diffs(idiff)
difftext = difftext & thisDiff(1)
Next
End If
आप मूल्य सेट करने के लिए स्वरूपण शुरू करने से पहले
Public Sub FormatDiff(ByRef diffs() As Variant, ByVal cell As Range)
Dim idiff As Long
Dim thisDiff() As Variant
Dim diffop As String
Dim difftext As String
cell.Font.Strikethrough = False
cell.Font.ColorIndex = 0
cell.Font.Bold = False
If Not diffs Then Exit Sub
Dim lastlen As Long
Dim thislen As Long
lastlen = 1
For idiff = 0 To UBound(diffs)
thisDiff = diffs(idiff)
diffop = thisDiff(0)
thislen = Len(thisDiff(1))
Select Case diffop
Case -1
cell.Characters(lastlen, thislen).Font.Strikethrough = True
cell.Characters(lastlen, thislen).Font.ColorIndex = 16 ' Dark Gray http://www.microsoft.com/technet/scriptcenter/resources/officetips/mar05/tips0329.mspx
Case 1
cell.Characters(lastlen, thislen).Font.Bold = True
cell.Characters(lastlen, thislen).Font.ColorIndex = 32 ' Blue
End Select
lastlen = lastlen + thislen
Next
End Sub
: यहाँ कोड है कि डिफ व्याख्या करती है और डेल्टा सेल स्वरूप है
अनुकूलन के लिए कुछ अवसर हैं, लेकिन अभी तक यह ठीक काम कर रहा है। जिसने भी मदद की उसका धन्यवाद!
ठंडा। खुशी है कि यह आपके लिए कारगर रहा। भविष्य में, यदि आप चाहें तो आप अपने प्रश्न का उत्तर दे सकते हैं। यह एक नीले टेक्स्टबॉक्स में पॉप अप होगा; दृष्टि से यह स्पष्ट है कि आपने इसे पोस्ट किया है। – Cheeso
Google diff/merge/पैच प्रोजेक्ट में अब एक (पूरी तरह प्रबंधित) सी # पोर्ट शामिल है। –