Skip to content

Commit 51fa9b4

Browse files
committed
fixed several issues
1 parent 8f63aa4 commit 51fa9b4

8 files changed

Lines changed: 90 additions & 64 deletions

File tree

ExcelOps-EpplusFreeFixCalcsEdition/EpplusFreeExcelDataOperations.SharedCode.vb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,11 @@ Namespace ExcelOps
6363
Else
6464
Me.WorkbookPackage.SaveAs(FullPath)
6565
End If
66-
Me.ReloadFromFile() 'WITHOUT THIS STEP, NEXT SAVE/SAVEAS MIGHT END UP IN EXCEPTION BECAUSE OF Epplus4 BUGS, THEREFORE SAVEAS IS USED INSTEAD OF SAVE
66+
With Nothing
67+
'WORKAROUND FOR NEXT SAVE/SAVEAS MIGHT END UP IN EXCEPTION BECAUSE OF Epplus4 BUGS, THEREFORE SAVEAS IS USED INSTEAD OF SAVE
68+
Me._FilePath = fileName
69+
Me.ReloadFromFile() 'WITHOUT THIS STEP , NEXT SAVE/SAVEAS MIGHT END UP IN EXCEPTION BECAUSE OF Epplus4 BUGS, THEREFORE SAVEAS IS USED INSTEAD OF SAVE
70+
End With
6771
Me._FilePath = FullPath.FullName
6872
End Sub
6973

ExcelOps-EpplusPolyform/EpplusPolyformExcelDataOperations.SharedCode.vb

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@ Namespace ExcelOps
3131
End Property
3232

3333
Protected Overrides Sub SaveInternal(cachedCalculationsOption As SaveOptionsForDisabledCalculationEngines)
34-
If Me.PasswordForOpening <> Nothing Then
35-
Me.WorkbookPackage.Save(Me.PasswordForOpening)
36-
Else
37-
Me.WorkbookPackage.Save()
38-
End If
34+
Me.SaveAsInternal(Me.FilePath, cachedCalculationsOption)
35+
'FOLLOWING CODE MIGHT END UP IN EXCEPTION BECAUSE OF Epplus4 BUGS, THEREFORE SAVEAS IS USED INSTEAD OF SAVE
36+
'If Me.PasswordForOpening <> Nothing Then
37+
' Me.WorkbookPackage.Save(Me.PasswordForOpening)
38+
'Else
39+
' Me.WorkbookPackage.Save()
40+
'End If
3941
End Sub
4042

4143
Protected Overrides Sub SaveInternal_ApplyCachedCalculationOption(cachedCalculationsOption As SaveOptionsForDisabledCalculationEngines)
@@ -61,6 +63,11 @@ Namespace ExcelOps
6163
Else
6264
Me.WorkbookPackage.SaveAs(FullPath)
6365
End If
66+
With Nothing
67+
'WORKAROUND FOR NEXT SAVE/SAVEAS MIGHT END UP IN EXCEPTION BECAUSE OF Epplus4 BUGS, THEREFORE SAVEAS IS USED INSTEAD OF SAVE
68+
Me._FilePath = fileName
69+
Me.ReloadFromFile() 'WITHOUT THIS STEP , NEXT SAVE/SAVEAS MIGHT END UP IN EXCEPTION BECAUSE OF Epplus4 BUGS, THEREFORE SAVEAS IS USED INSTEAD OF SAVE
70+
End With
6471
Me._FilePath = FullPath.FullName
6572
End Sub
6673

@@ -1068,7 +1075,11 @@ Namespace ExcelOps
10681075
If Me.Workbook.Worksheets(sheetName) Is Nothing Then Throw New ArgumentOutOfRangeException(NameOf(sheetName), "Sheet not found: " & sheetName)
10691076
Dim AllMergedCells = Me.Workbook.Worksheets(sheetName).MergedCells()
10701077
For MyCounter As Integer = 0 To AllMergedCells.Count - 1
1071-
Result.Add(New ExcelOps.ExcelRange(sheetName, AllMergedCells(MyCounter)))
1078+
If AllMergedCells(MyCounter) IsNot Nothing Then
1079+
Result.Add(New ExcelOps.ExcelRange(sheetName, AllMergedCells(MyCounter)))
1080+
Else
1081+
'unexpected situation: merged cell is nothing, but obviously can exist in collection of some XLSX files of real world sometimes, probably a bug in Epplus library after deleting sheets or merged cells?
1082+
End If
10721083
Next
10731084
Return Result
10741085
End Function

ExcelOps/ExcelOpsLowLevel/ExcelDataOperationsBase.vb

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -110,16 +110,16 @@ Namespace ExcelOps
110110
''' <param name="options">File and engine options</param>
111111
Protected Sub New(options As ExcelDataOperationsOptions)
112112
If options Is Nothing Then Throw New ArgumentNullException(NameOf(options))
113-
Dim ValidatedOptions As ExcelDataOperationsOptions = options.ApplyDefaultsFromEngineAndValidate(Me.DefaultCalculationOptions)
114-
Me.ValidateLoadOptions(ValidatedOptions)
115-
Me.LoadOptions = ValidatedOptions
116-
Me.CalculationModuleDisabled = ValidatedOptions.DisableCalculationEngine.Value
117-
Me.AutoCalculationOnLoad = Not ValidatedOptions.DisableInitialCalculation.Value
118-
If ValidatedOptions.DisableAutoCalculationInWorkbook.HasValue Then
119-
Me.AutoCalculationEnabledWorkbookSetting = Not ValidatedOptions.DisableAutoCalculationInWorkbook.Value
113+
Dim ValidatedOptionsClone As ExcelDataOperationsOptions = options.ApplyDefaultsFromEngineAndValidate(Me.DefaultCalculationOptions)
114+
Me.ValidateLoadOptions(ValidatedOptionsClone)
115+
Me.LoadOptions = ValidatedOptionsClone
116+
Me.CalculationModuleDisabled = ValidatedOptionsClone.DisableCalculationEngine.Value
117+
Me.AutoCalculationOnLoad = Not ValidatedOptionsClone.DisableInitialCalculation.Value
118+
If ValidatedOptionsClone.DisableAutoCalculationInWorkbook.HasValue Then
119+
Me.AutoCalculationEnabledWorkbookSetting = Not ValidatedOptionsClone.DisableAutoCalculationInWorkbook.Value
120120
End If
121-
Me.ReadOnly = (ValidatedOptions.FileWriteProtection = ExcelDataOperationsOptions.WriteProtectionMode.ReadOnly)
122-
Me.PasswordForOpening = ValidatedOptions.PasswordForOpening
121+
Me.ReadOnly = (ValidatedOptionsClone.FileWriteProtection = ExcelDataOperationsOptions.WriteProtectionMode.ReadOnly)
122+
Me.PasswordForOpening = ValidatedOptionsClone.PasswordForOpening
123123
End Sub
124124

125125
Protected Overridable Sub ValidateLoadOptions(options As ExcelDataOperationsOptions)
@@ -242,6 +242,7 @@ Namespace ExcelOps
242242
''' <summary>
243243
''' Reload a file from disk
244244
''' </summary>
245+
''' <remarks>If workbook is still opened, workbook state like selected sheet can be restored from memory, otherwise state will be restored as saved in file</remarks>
245246
Public Sub ReloadFromFile()
246247
Me.LoadAndInitializeWorkbookFile(Me.FilePath, Me.LoadOptions)
247248
End Sub
@@ -796,8 +797,10 @@ Namespace ExcelOps
796797

797798
Protected Sub LoadAndInitializeWorkbookFile(inputPath As String, options As ExcelDataOperationsOptions)
798799
If inputPath = Nothing Then Throw New ArgumentNullException(NameOf(inputPath))
799-
'1st, close an exsting workbook instance
800-
If Me.IsClosed = False Then Me.Close()
800+
'1st, close an exsting workbook instance, preserving most valuable states (e.g. selected sheet)
801+
If Me.IsClosed = False Then
802+
Me.Close()
803+
End If
801804
'Load the changed worksheet
802805
Me._FilePath = inputPath
803806
Dim file As New System.IO.FileInfo(inputPath)

ExcelOps/ExcelOpsLowLevel/ExcelDataOperationsOptions.vb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ Namespace ExcelOps
111111
End Function
112112

113113
''' <summary>
114-
''' Apply default options from engine if not set and validate the resulting combination
114+
''' Apply default options from engine if not set and validate the resulting combination (creates a clone of this options instance, doesn't change the current instance)
115115
''' </summary>
116116
''' <param name="calculationDefaultOptions">Default calculation options from engine</param>
117117
''' <returns>Validated options instance</returns>
50 KB
Binary file not shown.

ExcelOpsTest-SpireXls/TestFiles.vb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ Public NotInheritable Class TestFiles
2020
End Get
2121
End Property
2222

23+
Public Shared ReadOnly Property TestFileLastCellDetection01 As System.IO.FileInfo
24+
Get
25+
Return New System.IO.FileInfo(TestEnvironment.FullPathOfExistingTestFile("test_data", "LastCellDetection01.xlsx"))
26+
End Get
27+
End Property
28+
2329
Public Shared ReadOnly Property TestFileCircularReference01 As System.IO.FileInfo
2430
Get
2531
Return New System.IO.FileInfo(TestEnvironment.FullPathOfExistingTestFile("test_data", "CircularRefs01.xlsx"))
50 KB
Binary file not shown.

clone-build-files.ps1

Lines changed: 47 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,38 @@
1+
function Write-SourceCodeTargetFileWithReadonlyFlag {
2+
param (
3+
[Parameter(Mandatory)]
4+
[string] $TargetFile,
5+
6+
[Parameter(Mandatory)]
7+
[string[]] $SourceCode,
8+
9+
[switch] $SetReadOnly
10+
)
11+
12+
# Falls Zieldatei existiert und ReadOnly ist → temporär entfernen
13+
if (Test-Path -LiteralPath $TargetFile) {
14+
$item = Get-Item -LiteralPath $TargetFile
15+
if ($item.IsReadOnly) {
16+
$item.IsReadOnly = $false
17+
}
18+
}
19+
20+
# Schreiben mit passendem Encoding
21+
if ($PSVersionTable.PSVersion.Major -ge 7) {
22+
# pwsh: UTF8 ohne BOM wäre Default → wir erzwingen BOM
23+
$SourceCode | Out-File -LiteralPath $TargetFile -Encoding UTF8BOM -Force
24+
}
25+
else {
26+
# Windows PowerShell: UTF8 = UTF8 mit BOM
27+
$SourceCode | Out-File -LiteralPath $TargetFile -Encoding UTF8 -Force
28+
}
29+
30+
# Optional wieder ReadOnly setzen
31+
if ($SetReadOnly) {
32+
(Get-Item -LiteralPath $TargetFile).IsReadOnly = $true
33+
}
34+
}
35+
136
"TASK 1: RE-USE FILES test-data + TestEnvironment FROM MAIN-TEST TO UNIT-TEST-DEPENDENCY-PROJECTS"
237

338
# clone files test-data => FreeSpireXls
@@ -24,62 +59,29 @@ copy-item ExcelOpsTest/Console.vb ExcelOpsTest-SpireXls/
2459
"TASK 2: INCLUDE LATEST LOGIC FROM FreeSpireXls edition into SpireXls edition"
2560

2661
# clone files FreeSpireXls => SpireXls
27-
$SourceCode = (gc ExcelOps-FreeSpireXls/FreeSpireXlsDataOperations.SharedCode.vb) -replace 'Partial Public Class FreeSpireXlsDataOperations', 'Partial Public Class SpireXlsDataOperations'
28-
if ($PSVersionTable.PSVersion.Major -ge 7)
29-
{
30-
# "pwsh" -> force encoding UTF8BOM
31-
$SourceCode | Out-File -encoding UTF8BOM ExcelOps-SpireXls/SpireXlsDataOperations.SharedCode.vb
32-
}
33-
else
34-
{
35-
# "powershell" -> UTF8BOM not supported, but BOM added by default for UTF8
36-
$SourceCode | Out-File -encoding UTF8 ExcelOps-SpireXls/SpireXlsDataOperations.SharedCode.vb
37-
}
62+
$SourceCode = (gc -Raw ExcelOps-FreeSpireXls/FreeSpireXlsDataOperations.SharedCode.vb) -replace 'Partial Public Class FreeSpireXlsDataOperations', 'Partial Public Class SpireXlsDataOperations'
63+
$TargetFile = 'ExcelOps-SpireXls/SpireXlsDataOperations.SharedCode.vb'
64+
Write-SourceCodeTargetFileWithReadonlyFlag -TargetFile $TargetFile -SourceCode $SourceCode -SetReadOnly
3865

3966
"TASK 3: INCLUDE LATEST LOGIC FROM EpplusFreeFixCalcsEdition edition into SpireXls edition"
4067

4168
# clone files EpplusFreeFixCalcsEdition => EpplusPolyform
42-
$SourceCode = (gc ExcelOps-EpplusFreeFixCalcsEdition/EpplusFreeExcelDataOperations.SharedCode.vb) -replace 'Partial Public Class EpplusFreeExcelDataOperations', 'Partial Public Class EpplusPolyformExcelDataOperations' -replace 'CompuMaster.Epplus4', 'OfficeOpenXml' -replace 'EpplusFreeExcelDataOperations', 'EpplusPolyformExcelDataOperations'
43-
if ($PSVersionTable.PSVersion.Major -ge 7)
44-
{
45-
# "pwsh" -> force encoding UTF8BOM
46-
$SourceCode | Out-File -encoding UTF8BOM ExcelOps-EpplusPolyform/EpplusPolyformExcelDataOperations.SharedCode.vb
47-
}
48-
else
49-
{
50-
# "powershell" -> UTF8BOM not supported, but BOM added by default for UTF8
51-
$SourceCode | Out-File -encoding UTF8 ExcelOps-EpplusPolyform/EpplusPolyformExcelDataOperations.SharedCode.vb
52-
}
69+
$SourceCode = (gc -Raw ExcelOps-EpplusFreeFixCalcsEdition/EpplusFreeExcelDataOperations.SharedCode.vb) -replace 'Partial Public Class EpplusFreeExcelDataOperations', 'Partial Public Class EpplusPolyformExcelDataOperations' -replace 'CompuMaster.Epplus4', 'OfficeOpenXml' -replace 'EpplusFreeExcelDataOperations', 'EpplusPolyformExcelDataOperations'
70+
$TargetFile = 'ExcelOps-EpplusPolyform/EpplusPolyformExcelDataOperations.SharedCode.vb'
71+
Write-SourceCodeTargetFileWithReadonlyFlag -TargetFile $TargetFile -SourceCode $SourceCode -SetReadOnly
5372

5473
"TASK 4: INCLUDE LATEST LOGIC FROM XlsEpplusFixCalcsEdition edition into XlsEpplusPolyformEdition edition"
5574

5675
# clone files XlsEpplusFixCalcsEdition => XlsEpplusPolyformEdition
57-
$SourceCode = (gc CM.Data.EpplusFixCalcsEdition/XlsEpplusFixCalcsEdition.vb) -replace 'Public Class XlsEpplusFixCalcsEdition', 'Public Class XlsEpplusPolyformEdition' -replace 'CompuMaster.Epplus4', 'OfficeOpenXml'
58-
if ($PSVersionTable.PSVersion.Major -ge 7)
59-
{
60-
# "pwsh" -> force encoding UTF8BOM
61-
$SourceCode | Out-File -encoding UTF8BOM CM.Data.EpplusPolyformEdition/XlsEpplusPolyformEdition.vb
62-
}
63-
else
64-
{
65-
# "powershell" -> UTF8BOM not supported, but BOM added by default for UTF8
66-
$SourceCode | Out-File -encoding UTF8 CM.Data.EpplusPolyformEdition/XlsEpplusPolyformEdition.vb
67-
}
76+
$SourceCode = (gc -Raw CM.Data.EpplusFixCalcsEdition/XlsEpplusFixCalcsEdition.vb) -replace 'Public Class XlsEpplusFixCalcsEdition', 'Public Class XlsEpplusPolyformEdition' -replace 'CompuMaster.Epplus4', 'OfficeOpenXml'
77+
$TargetFile = 'CM.Data.EpplusPolyformEdition/XlsEpplusPolyformEdition.vb'
78+
Write-SourceCodeTargetFileWithReadonlyFlag -TargetFile $TargetFile -SourceCode $SourceCode -SetReadOnly
6879

6980
"TASK 5: INCLUDE LATEST UNIT TEST LOGIC FROM CmDataXlsEpplusFixCalcsEditionTest edition into CmDataXlsEpplusPolyformEditionTest edition"
7081

7182
# clong unit test files
72-
$SourceCode = (gc ExcelOpsTest/Data/CmDataXlsEpplusFixCalcsEditionTest.vb) -replace 'Public Class CmDataXlsEpplusFixCalcsEditionTest', 'Public Class CmDataXlsEpplusPolyformEditionTest' -replace 'XlsEpplusFixCalcsEdition', 'XlsEpplusPolyformEdition'
73-
if ($PSVersionTable.PSVersion.Major -ge 7)
74-
{
75-
# "pwsh" -> force encoding UTF8BOM
76-
$SourceCode | Out-File -encoding UTF8BOM ExcelOpsTest/Data/CmDataXlsEpplusPolyformEditionTest.vb
77-
}
78-
else
79-
{
80-
# "powershell" -> UTF8BOM not supported, but BOM added by default for UTF8
81-
$SourceCode | Out-File -encoding UTF8 ExcelOpsTest/Data/CmDataXlsEpplusPolyformEditionTest.vb
82-
}
83-
83+
$SourceCode = (gc -Raw ExcelOpsTest/Data/CmDataXlsEpplusFixCalcsEditionTest.vb) -replace 'Public Class CmDataXlsEpplusFixCalcsEditionTest', 'Public Class CmDataXlsEpplusPolyformEditionTest' -replace 'XlsEpplusFixCalcsEdition', 'XlsEpplusPolyformEdition'
84+
$TargetFile = 'ExcelOpsTest/Data/CmDataXlsEpplusPolyformEditionTest.vb'
85+
Write-SourceCodeTargetFileWithReadonlyFlag -TargetFile $TargetFile -SourceCode $SourceCode -SetReadOnly
8486

8587
"TASKS COMPLETED."

0 commit comments

Comments
 (0)