2 <implements type="Automation" id="dispatcher">
3 <property name="PluginEvent">
6 <property name="PluginDescription">
9 <property name="PluginFileFilters">
12 <property name="PluginIsAutomatic">
15 <method name="UnpackFile"/>
16 <method name="PackFile"/>
17 <method name="IsFolder"/>
18 <method name="UnpackFolder"/>
19 <method name="PackFolder"/>
20 <method name="ShowSettingsDialog"/>
23 <script language="VBS">
25 '/////////////////////////////////////////////////////////////////////////////
26 ' This is a plugin for WinMerge.
27 ' It will display the text content of MS Excel files.
28 ' Copyright (C) 2005-2014 Takashi Sawanaka
30 ' This program is free software; you can redistribute it and/or modify
31 ' it under the terms of the GNU General Public License as published by
32 ' the Free Software Foundation; either version 2 of the License, or
33 ' (at your option) any later version.
35 ' This program is distributed in the hope that it will be useful,
36 ' but WITHOUT ANY WARRANTY; without even the implied warranty of
37 ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 ' GNU General Public License for more details.
40 ' You should have received a copy of the GNU General Public License
41 ' along with this program; if not, write to the Free Software
42 ' Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
47 Const RegKeyPath = "HKCU\Software\Thingamahoochie\WinMerge\Plugins\CompareMSExcelFiles.sct\"
48 Dim MsgCannotGetMacros
49 MsgCannotGetMacros = "Cannot get Macros." & vbCrLf & _
50 " To allow WinMerge to compare macros, use MS Office to alter the settings in the Macro Security for the current application." & vbCrLf & _
51 " The Trust access to Visual Basic Project feature should be turned on to use this feature in WinMerge." & vbCrLf
53 Dim fso: Set fso = CreateObject("Scripting.FileSystemObject")
54 Dim wsh: Set wsh = CreateObject("WScript.Shell")
56 Function isAccessibleVBAProject(wbk)
60 count = wbk.VBProject.VBComponents.Count
61 isAccessibleVBAProject = (count > 0)
64 Function regRead(Key, DefaultValue)
65 regRead = DefaultValue
67 regRead = wsh.RegRead(Key)
70 Function writeObjectProperties(fo, items)
74 fo.WriteLine o.Name & ": " & o.Value
78 Function writeCellValues(fo, sht)
79 Dim varCells, row, col, ary()
80 varCells = sht.UsedRange.Value
81 If TypeName(varCells) = "String" Then
83 ElseIf Not IsEmpty(varCells) Then
84 ReDim ary(UBound(varCells, 2))
86 For row = 1 To UBound(varCells, 1)
87 For col = 1 To UBound(varCells, 2)
88 ary(col - 1) = CStr(varCells(row, col))
89 If Err.Number <> 0 Then
90 ary(col - 1) = "Error" & Err.Number
94 fo.WriteLine Join(ary, vbTab)
99 Function GetAddr(row, col)
103 GetAddr = Chr(65 + (c Mod 26)) & GetAddr
106 GetAddr = GetAddr & row
109 Function writeFormulas(fo, sht)
110 Dim row, col, rowOffset, colOffset, varCells, formula
111 rowOffset = sht.UsedRange.Row
112 colOffset = sht.UsedRange.Column
113 varCells = sht.UsedRange.Formula
114 If TypeName(varCells) = "String" Then
115 fo.WriteLine GetAddr(rowOffset - 1, colOffset - 1) & ": " & varCells
117 For row = 1 To UBound(varCells, 1)
118 For col = 1 To UBound(varCells, 2)
119 formula = varCells(row, col)
120 If Left(formula, 1) = "=" Then
121 fo.WriteLine GetAddr(row + rowOffset - 1, col + colOffset - 1) & ": " & formula
128 Function getUsedRangeIncludingShapes(sht)
133 For Each shp In sht.Shapes
134 Set rng = shp.BottomRightCell
135 If row_max < rng.Row + rng.Rows.Count - 1 Then row_max = rng.Row + rng.Rows.Count - 1
136 If col_max < rng.Column + rng.Columns.Count - 1 Then col_max = rng.Column + rng.Columns.Count - 1
138 Set rng = sht.UsedRange
139 If row_max < rng.Row + rng.Rows.Count - 1 Then row_max = rng.Row + rng.Rows.Count - 1
140 If col_max < rng.Column + rng.Columns.Count - 1 Then col_max = rng.Column + rng.Columns.Count - 1
141 Set getUsedRangeIncludingShapes = sht.Range("A1", sht.Cells(row_max, col_max))
144 Sub ungroupShapes(sht)
148 cnt = sht.Shapes.Count
149 For Each shp In sht.Shapes
152 Loop While cnt <> sht.Shapes.Count
155 Function writeTextsInShapes(fo, sht)
158 For Each shp In sht.Shapes
159 fo.WriteLine shp.Name & ": " & shp.TextFrame.Characters.Text
164 Function getModuleExtension(cmp)
167 getModuleExtension = ".cls"
169 getModuleExtension = ".frm"
171 getModuleExtension = ".bas"
175 Function saveRangeAsImage(sht, rng, filename)
179 saveRangeAsImage = True
184 Set shtNew = sht.Parent.Sheets.Add
185 Set obj = sht.Parent.Charts.Add
186 rng.CopyPicture 1, 2 ' xlScreen=1, xlBitmap=2
187 Set obj = obj.Location(2, shtNew.Name) ' xlLocationAsObject=2
189 If sht.Application.Version <= 11 Then
190 obj.Parent.Width = rng.Width + 8
191 obj.Parent.Height = rng.Height + 8
193 obj.Parent.Width = rng.Width
194 obj.Parent.Height = rng.Height
196 If Err.Number = 0 Then
198 obj.Export filename, "PNG"
200 If Err.Number <> 0 Then
201 saveRangeAsImage = False
208 Function getTimeStamp()
211 ms = Fix((tm - Fix(tm)) * 1000)
213 getTimeStamp = (tm \ (60 * 60)) & ":" & ((tm \ 60) Mod 60) & ":" & (tm Mod 60) & "." & ms
216 Function findRowByPosition(sht, ByVal rowBegin, ByVal rowEnd, ByVal pos)
217 Dim height, rowPrev, row, rowBeginOrg
219 rowBeginOrg = rowBegin
222 height = sht.Range("A" & rowBeginOrg & ":A" & row).height
228 row = (rowEnd - rowBegin) \ 2 + rowBegin
229 If row = rowPrev Then
230 findRowByPosition = row
237 Function saveSheetAsImage(sht, basefilename)
238 Dim rngUsed, rngImage, row, rowEnd, filename, num
239 Set rngUsed = getUsedRangeIncludingShapes(sht)
243 rowEnd = findRowByPosition(sht, row, rngUsed.Row + rngUsed.Rows.Count - 1, 5000)
244 Set rngImage = sht.Range(sht.Cells(row, rngUsed.Column), sht.Cells(rowEnd, rngUsed.Column + rngUsed.Columns.Count - 1))
245 filename = basefilename & "(" & num & ").png"
246 If Not saveRangeAsImage(sht, rngImage, filename) Then
248 Set shtNew = sht.Parent.Sheets.Add
249 shtNew.Range("A1") = getTimeStamp() & ": Error" & Err.Number & ": " & Err.Description
250 shtNew.Columns.AutoFit
251 saveRangeAsImage shtNew, shtNew.Range("A1"), filename
256 Loop While row < rngUsed.row + rngUsed.Rows.Count - 1
259 Function get_PluginEvent()
260 get_PluginEvent = "FILE_FOLDER_PACK_UNPACK"
263 Function get_PluginDescription()
264 get_PluginDescription = "Display the text content of MS Excel files"
267 Function get_PluginFileFilters()
268 get_PluginFileFilters = "\.xls(\..*)?$;\.xlsx(\..*)?$;\.xlsm(\..*)?$;\.xlsb(\..*)?;\.xla(\..*)?$;\.xlax(\..*)?$;\.xltx(\..*)?$;\.xltm(\..*)?$"
271 Function get_PluginIsAutomatic()
272 get_PluginIsAutomatic = True
275 Function UnpackFile(fileSrc, fileDst, pbChanged, pSubcode)
282 Set fo = fso.CreateTextFile(fileDst, True, True)
284 Set xl = CreateObject("Excel.Application")
285 xl.EnableEvents = False
286 xl.DisplayAlerts = False
288 Set wbk = xl.Workbooks.Open(fileSrc)
292 If regRead(RegKeyPath & "CompareDocumentProperties", False) Then
293 fo.WriteLine "[Document Properties]"
294 writeObjectProperties fo, wbk.BuiltinDocumentProperties
298 If regRead(RegKeyPath & "CompareNames", True) Then
299 fo.WriteLine "[Names]"
300 writeObjectProperties fo, wbk.Names
304 For Each sht In wbk.Worksheets
305 If regRead(RegKeyPath & "CompareCellValues", True) Then
306 fo.WriteLine "[" & sht.Name & "]"
307 writeCellValues fo, sht
310 If regRead(RegKeyPath & "CompareFormulas", False) Then
311 fo.WriteLine "[" & sht.Name & ".Formulas]"
312 writeFormulas fo, sht
315 If regRead(RegKeyPath & "CompareTextsInShapes", True) Then
316 fo.WriteLine "[" & sht.Name & ".Shapes]"
318 writeTextsInShapes fo, sht
323 If regRead(RegKeyPath & "CompareVBAMacros", True) Then
324 If Not isAccessibleVBAProject(wbk) Then
325 fo.WriteLine MsgCannotGetMacros
327 For Each cmp In wbk.VBProject.VBComponents
328 fo.WriteLine "[CodeModule." & cmp.Name & "]"
329 If cmp.CodeModule.CountOfLines > 0 Then
330 fo.WriteLine cmp.CodeModule.Lines(1, cmp.CodeModule.CountOfLines)
350 Function PackFile(fileSrc, fileDst, pbChanged, pSubcode)
354 Function IsFolder(file)
355 IsFolder = regRead(RegKeyPath & "UnpackToFolder", False)
358 Function UnpackFolder(fileSrc, folderDst, pbChanged, pSubcode)
366 If Not fso.FolderExists(folderDst) Then fso.CreateFolder folderDst
368 Set xl = CreateObject("Excel.Application")
369 xl.EnableEvents = False
370 xl.DisplayAlerts = False
372 Set wbk = xl.Workbooks.Open(fileSrc)
376 If regRead(RegKeyPath & "CompareDocumentProperties", False) Then
377 Set fo = fso.CreateTextFile(fso.BuildPath(folderDst, "(0)DocumentProperties.txt"), True, True)
378 writeObjectProperties fo, wbk.BuiltinDocumentProperties
382 If regRead(RegKeyPath & "CompareNames", True) Then
383 Set fo = fso.CreateTextFile(fso.BuildPath(folderDst, "(0)Names.txt"), True, True)
384 writeObjectProperties fo, wbk.Names
389 For Each sht In wbk.Worksheets
390 If regRead(RegKeyPath & "CompareCellValues", True) Then
391 Set fo = fso.CreateTextFile(fso.BuildPath(folderDst, "(" & No & ")" & sht.Name & ".txt"), True, True)
392 writeCellValues fo, sht
396 If regRead(RegKeyPath & "CompareFormulas", False) Then
397 Set fo = fso.CreateTextFile(fso.BuildPath(folderDst, "(" & No & ")" & sht.Name & "_Formulas.txt"), True, True)
398 writeFormulas fo, sht
402 If regRead(RegKeyPath & "CompareTextsInShapes", True) Then
403 Set fo = fso.CreateTextFile(fso.BuildPath(folderDst, "(" & No & ")" & sht.Name & "_Shapes.txt"), True, True)
405 writeTextsInShapes fo, sht
409 If regRead(RegKeyPath & "CompareWorksheetsAsImage", True) Then
410 saveSheetAsImage sht, fso.BuildPath(folderDst, "(" & No & ")" & sht.Name)
414 If regRead(RegKeyPath & "CompareVBAMacros", True) Then
415 If Not isAccessibleVBAProject(wbk) Then
416 Set fo = fso.CreateTextFile(fso.BuildPath(folderDst, "CannotGetMacros.bas"), True, True)
417 fo.WriteLine MsgCannotGetMacros
421 For Each cmp In wbk.VBProject.VBComponents
422 cmp.Export fso.BuildPath(folderDst, cmp.Name & getModuleExtension(cmp))
438 Function PackFolder(fileSrc, folderDst, pbChanged, pSubcode)
442 Function ShowSettingsDialog()
443 Dim tname: tname = fso.BuildPath(fso.GetSpecialFolder(2), fso.GetTempName() & ".hta")
444 Dim tfile: Set tfile = fso.CreateTextFile(tname)
445 tfile.Write getResource("dialog1")
447 Run wsh, "mshta.exe """ & tname & """"
457 <resource id="dialog1">
461 <title>CompareMSExcelFiles.sct WinMerge Plugin Options</title>
462 <meta content="text/html" charset="Shift_JIS">
464 body { background-color: lightgray; }
465 ul { list-style:none; }
467 <script type="text/javascript">
468 var REGKEY_PATH = "HKCU\\Software\\Thingamahoochie\\WinMerge\\Plugins\\CompareMSExcelFiles.sct\\";
470 function regRead(key, defaultValue) {
472 return (new ActiveXObject("WScript.Shell")).RegRead(key);
478 function regWrite(key, value, type) {
479 (new ActiveXObject("WScript.Shell")).RegWrite(key, value, type);
484 var w = 600, h = 400;
485 window.resizeTo(w, h);
486 window.moveTo((screen.width - w) / 2, (screen.height - h) / 2);
488 cboLanguage.selectedIndex = navigator.browserLanguage.substr(0, 2) === 'ja' ? 1 : 0;
489 setLanguage(navigator.browserLanguage);
490 chkUnpackToFolder.checked = regRead(REGKEY_PATH + "UnpackToFolder", false);
491 chkCompareDocumentProperties.checked = regRead(REGKEY_PATH + "CompareDocumentProperties", false);
492 chkCompareNames.checked = regRead(REGKEY_PATH + "CompareNames", true);
493 chkCompareCellValues.checked = regRead(REGKEY_PATH + "CompareCellValues", true);
494 chkCompareWorksheetsAsImage.checked = regRead(REGKEY_PATH + "CompareWorksheetsAsImage", true);
495 chkCompareFormulas.checked = regRead(REGKEY_PATH + "CompareFormulas", false);
496 chkCompareTextsInShapes.checked = regRead(REGKEY_PATH + "CompareTextsInShapes", true);
497 chkCompareVBAMacros.checked = regRead(REGKEY_PATH + "CompareVBAMacros", true);
498 chkUnpackToFolder_onclick();
499 chkCompareWorksheetsAsImage_onclick();
502 function setLanguage(lang) {
503 var div = document.getElementById("language") || document.createElement('div')
505 var html = '­<style>';
506 if (lang.substr(0, 2).toLowerCase() === 'ja') {
507 html += '.en { display: none } .ja { display: inline }';
509 html += '.ja { display: none } .en { display: inline }';
511 div.innerHTML = html;
512 if (!document.getElementById("language"))
513 document.body.appendChild(div);
516 function cboLanguage_onclick() {
517 setLanguage(cboLanguage.options[cboLanguage.selectedIndex].text);
520 function chkUnpackToFolder_onclick() {
521 if (!chkUnpackToFolder.checked)
522 chkCompareWorksheetsAsImage.checked = false;
525 function chkCompareWorksheetsAsImage_onclick() {
526 if (chkCompareWorksheetsAsImage.checked)
527 chkUnpackToFolder.checked = true;
530 function btnOk_onclick() {
531 regWrite(REGKEY_PATH + "UnpackToFolder", chkUnpackToFolder.checked, "REG_DWORD");
532 regWrite(REGKEY_PATH + "CompareDocumentProperties", chkCompareDocumentProperties.checked, "REG_DWORD");
533 regWrite(REGKEY_PATH + "CompareNames", chkCompareNames.checked, "REG_DWORD");
534 regWrite(REGKEY_PATH + "CompareCellValues", chkCompareCellValues.checked, "REG_DWORD");
535 regWrite(REGKEY_PATH + "CompareWorksheetsAsImage", chkCompareWorksheetsAsImage.checked, "REG_DWORD");
536 regWrite(REGKEY_PATH + "CompareFormulas", chkCompareFormulas.checked, "REG_DWORD");
537 regWrite(REGKEY_PATH + "CompareTextsInShapes", chkCompareTextsInShapes.checked, "REG_DWORD");
538 regWrite(REGKEY_PATH + "CompareVBAMacros", chkCompareVBAMacros.checked, "REG_DWORD"); window.close();
541 function btnCancel_onclick() {
547 <body onload="onload();">
551 <label class="en">Language: </label>
552 <label class="ja">
\8c¾
\8cê: </label>
553 <select id="cboLanguage" onclick="cboLanguage_onclick();" >
554 <option value="English">English</option>
555 <option value="Japanese">Japanese</option>
561 <input id="chkUnpackToFolder" type="checkbox" onclick="chkUnpackToFolder_onclick();"/>
562 <label class="en">Extract workbook data to multiple files </label>
563 <label class="ja">
\83\8f\81[
\83N
\83u
\83b
\83N
\82Ì
\8fî
\95ñ
\82ð
\95¡
\90\94\83t
\83@
\83C
\83\8b\82É
\93W
\8aJ
\82·
\82é </label>
566 <input id="chkCompareDocumentProperties" type="checkbox" />
567 <label class="en">Compare document properties </label>
568 <label class="ja">
\83h
\83L
\83\85\83\81\83\93\83g
\83v
\83\8d\83p
\83e
\83B
\82ð
\94ä
\8ar
\82·
\82é </label>
571 <input id="chkCompareNames" type="checkbox" />
572 <label class="en">Compare names </label>
573 <label class="ja">
\96¼
\91O
\82Ì
\92è
\8b`
\82ð
\94ä
\8ar
\82·
\82é </label>
576 <input id="chkCompareCellValues" type="checkbox" />
577 <label class="en">Compare cell values </label>
578 <label class="ja">
\8ae
\83Z
\83\8b\82Ì
\92l
\82ð
\94ä
\8ar
\82·
\82é </label>
581 <input id="chkCompareWorksheetsAsImage" type="checkbox" onclick="chkCompareWorksheetsAsImage_onclick();"/>
582 <label class="en">Compare worksheets as image (very slow)</label>
583 <label class="ja">
\83\8f\81[
\83N
\83V
\81[
\83g
\82ð
\89æ
\91\9c\89»
\82µ
\82Ä
\94ä
\8ar
\82·
\82é (
\8f\88\97\9d\8e\9e\8aÔ
\91\9d\91å)</label>
586 <input id="chkCompareFormulas" type="checkbox" />
587 <label class="en">Compare formulas</label>
588 <label class="ja">
\90\94\8e®
\82ð
\94ä
\8ar
\82·
\82é</label>
591 <input id="chkCompareTextsInShapes" type="checkbox" />
592 <label class="en">Compare texts in shapes </label>
593 <label class="ja">
\90}
\8c`
\93à
\82Ì
\83e
\83L
\83X
\83g
\82ð
\94ä
\8ar
\82·
\82é </label>
596 <input id="chkCompareVBAMacros" type="checkbox" />
597 <label class="en">Compare VBA macros </label>
598 <label class="ja">VBA
\83}
\83N
\83\8d\82ð
\94ä
\8ar
\82·
\82é </label>
603 <input class="en" type="button" onclick="btnOk_onclick();" value="OK" />
604 <input class="en" type="button" onclick="btnCancel_onclick();" value="Cancel" />
605 <input class="ja" type="button" onclick="btnOk_onclick();" value="OK" />
606 <input class="ja" type="button" onclick="btnCancel_onclick();" value="
\83L
\83\83\83\93\83Z
\83\8b" />