summaryrefslogtreecommitdiff
path: root/wizards
diff options
context:
space:
mode:
Diffstat (limited to 'wizards')
-rw-r--r--wizards/source/scriptforge/SF_Utils.xba2
-rw-r--r--wizards/source/scriptforge/python/scriptforge.py6
-rw-r--r--wizards/source/sfdocuments/SF_Calc.xba224
3 files changed, 228 insertions, 4 deletions
diff --git a/wizards/source/scriptforge/SF_Utils.xba b/wizards/source/scriptforge/SF_Utils.xba
index 5dbe667a52f0..e26cca66a776 100644
--- a/wizards/source/scriptforge/SF_Utils.xba
+++ b/wizards/source/scriptforge/SF_Utils.xba
@@ -1107,4 +1107,4 @@ Finally:
End Function ' ScriptForge.SF_Utils._VarTypeObj
REM ================================================= END OF SCRIPTFORGE.SF_UTILS
-</script:module>
+</script:module> \ No newline at end of file
diff --git a/wizards/source/scriptforge/python/scriptforge.py b/wizards/source/scriptforge/python/scriptforge.py
index c1261a14fc40..600d8469e623 100644
--- a/wizards/source/scriptforge/python/scriptforge.py
+++ b/wizards/source/scriptforge/python/scriptforge.py
@@ -2086,6 +2086,12 @@ class SFDocuments:
def ClearValues(self, range):
return self.ExecMethod(self.vbMethod, 'ClearValues', range)
+ def CompactLeft(self, range, wholecolumn = False, filterformula = ''):
+ return self.ExecMethod(self.vbMethod, 'CompactLeft', range, wholecolumn, filterformula)
+
+ def CompactUp(self, range, wholerow = False, filterformula = ''):
+ return self.ExecMethod(self.vbMethod, 'CompactUp', range, wholerow, filterformula)
+
def CopySheet(self, sheetname, newname, beforesheet = 32768):
sheet = (sheetname.objectreference if isinstance(sheetname, SFDocuments.SF_CalcReference) else sheetname)
return self.ExecMethod(self.vbMethod + self.flgObject, 'CopySheet', sheet, newname, beforesheet)
diff --git a/wizards/source/sfdocuments/SF_Calc.xba b/wizards/source/sfdocuments/SF_Calc.xba
index bc5681992eec..33a523874f39 100644
--- a/wizards/source/sfdocuments/SF_Calc.xba
+++ b/wizards/source/sfdocuments/SF_Calc.xba
@@ -90,7 +90,6 @@ Private Const RANGEEXPORTERROR = &quot;RANGEEXPORTERROR&quot;
REM ============================================================= PRIVATE MEMBERS
Private [Me] As Object
-Private [_Parent] As Object
Private [_Super] As Object &apos; Document superclass, which the current instance is a subclass of
Private ObjectType As String &apos; Must be CALC
Private ServiceName As String
@@ -137,7 +136,6 @@ REM ====================================================== CONSTRUCTOR/DESTRUCTO
REM -----------------------------------------------------------------------------
Private Sub Class_Initialize()
Set [Me] = Nothing
- Set [_Parent] = Nothing
Set [_Super] = Nothing
ObjectType = &quot;CALC&quot;
ServiceName = &quot;SFDocuments.Calc&quot;
@@ -652,6 +650,224 @@ Catch:
End Sub &apos; SF_Documents.SF_Calc.ClearValues
REM -----------------------------------------------------------------------------
+Public Function CompactLeft(Optional ByVal Range As Variant _
+ , Optional ByVal WholeColumn As Variant _
+ , Optional ByVal FilterFormula As Variant _
+ ) As String
+&apos;&apos;&apos; Delete the columns of a specified range matching a filter expressed as a formula
+&apos;&apos;&apos; applied on each column.
+&apos;&apos;&apos; The deleted cells can span whole columns or be limited to the height of the range
+&apos;&apos;&apos; The execution of the method has no effect on the current selection
+&apos;&apos;&apos; Args:
+&apos;&apos;&apos; Range: the range in which cells have to be erased, as a string
+&apos;&apos;&apos; WholeColumn: when True (default = False), erase whole columns
+&apos;&apos;&apos; FilterFormula: the formula to be applied on each column.
+&apos;&apos;&apos; The column is erased when the formula results in True,
+&apos;&apos;&apos; The formula shall probably involve one or more cells of the first column of the range..
+&apos;&apos;&apos; By default, a column is erased when all the cells of the column are empty,
+&apos;&apos;&apos; i.e. suppose the range is &quot;A1:J200&quot; (height = 0) the default value becomes
+&apos;&apos;&apos; &quot;=(COUNTBLANK(A1:A200)=200)&quot;
+&apos;&apos;&apos; Returns:
+&apos;&apos;&apos; A string representing the location of the initial range after compaction,
+&apos;&apos;&apos; or the zero-length string if the whole range has been deleted
+&apos;&apos;&apos; Examples:
+&apos;&apos;&apos; newrange = oDoc.CompactLeft(&quot;SheetX.G1:L10&quot;) &apos; All empty columns of the range are suppressed
+&apos;&apos;&apos; newrange = oDoc.CompactLeft(&quot;SheetX.G1:L10&quot;, WholeColumn := True, FilterFormula := &quot;=(G$7=&quot;&quot;X&quot;&quot;)&quot;)
+&apos;&apos;&apos; &apos; The columns having a &quot;X&quot; in row 7 are completely suppressed
+
+Dim sCompact As String &apos; Return value
+Dim oSourceAddress As Object &apos; Alias of Range as _Address
+Dim lLastRow As Long &apos; Last used row number in the sheet containing Range
+Dim sFormulaRange As String &apos; Range, as a string, where the FilterFormula must be stored
+Dim vCompact As Variant &apos; Array of Boolean values indicating which columns should be erased
+Dim lCountDeleted As Long &apos; Count the deleted columns
+Dim lCountToDelete As Long &apos; Count contiguous columns to be deleted at once
+Dim sPartialRange As String &apos; Contiguous columns to be deleted
+Dim i As Long
+
+Const cstThisSub = &quot;SFDocuments.Calc.CompactLeft&quot;
+Const cstSubArgs = &quot;Range, [WholeColumn=False], [FilterFormula=&quot;&quot;&quot;&quot;]&quot;
+
+ If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
+ sCompact = &quot;&quot;
+
+Check:
+ If IsMissing(WholeColumn) Or IsEmpty(WholeColumn) Then WholeColumn = False
+ If IsMissing(FilterFormula) Or IsEmpty(FilterFormula) Then FilterFormula = &quot;&quot;
+ If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
+ If Not _IsStillAlive(True) Then GoTo Finally
+ If Not ScriptForge.SF_Utils._Validate(Range, &quot;Range&quot;, V_STRING) Then GoTo Finally
+ If Not ScriptForge.SF_Utils._Validate(WholeColumn, &quot;WholeColumn&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
+ If Not ScriptForge.SF_Utils._Validate(FilterFormula, &quot;FilterFormula&quot;, V_STRING) Then GoTo Finally
+ End If
+
+Try:
+ Set oSourceAddress = _ParseAddress(Range)
+
+ With oSourceAddress
+
+ &apos; Set the default formula =&gt; all cells are blank
+ If FilterFormula = &quot;&quot; Then FilterFormula = Printf(&quot;=(COUNTBLANK(%C1%R1:%C1%R2)-&quot; &amp; .Height &amp; &quot;=0)&quot;, Range)
+ &apos; Compute the range where to apply the formula
+ lLastRow = LastRow(.SheetName)
+ sFormulaRange = Offset(Range, lLastRow - .XCellRange.RangeAddress.StartColumn + 1, , 1)
+ SetFormula(sFormulaRange, FilterFormula)
+ &apos; Get the columns to compact: 0 = False, 1 = True
+ vCompact = GetValue(sFormulaRange)
+ ClearAll(sFormulaRange)
+
+ &apos; Iterates from the last to the first column of the range and remove the columns that match the filter
+ &apos; by groups of contiguous columns
+ lCountDeleted = 0
+ lCountToDelete = 0
+ For i = UBound(vCompact) To 0 Step -1
+ If vCompact(i) = 1 Then lCountToDelete = lCountToDelete + 1
+ If i &gt; 0 And vCompact(i) = 1 Then
+ &apos; Do nothing
+ ElseIf lCountToDelete &gt; 0 Then &apos; The current column must be kept but columns at the left must be removed
+ &apos; Do not forget when the 1st column must be removed
+ sPartialRange = Offset(Range, , Iif(i = 0 And vCompact(i) = 1, 0, i + 1), , lCountToDelete)
+ ShiftLeft(sPartialRange, WholeColumn)
+ lCountDeleted = lCountDeleted + lCountToDelete
+ lCountToDelete = 0
+ End If
+ Next i
+
+ &apos; Compute the final range position
+ If lCountDeleted &lt; .Width Then sCompact = Offset(Range, 0, 0, , .Width - lCountDeleted)
+
+ &apos; Push rightwards the cells that migrated leftwards irrelevantly
+ If Not WholeColumn Then
+ If Len(sCompact) &gt; 0 Then
+ sPartialRange = Offset(sCompact, 0, .Width - lCountDeleted, , lCountDeleted)
+ Else
+ sPartialRange = .RangeName
+ End If
+ ShiftRight(sPartialRange, WholeColumn := False)
+ End If
+
+ End With
+
+Finally:
+ CompactLeft = sCompact
+ ScriptForge.SF_Utils._ExitFunction(cstThisSub)
+ Exit Function
+Catch:
+ &apos; When error, return the original range
+ If Not IsNull(oSourceAddress) Then sCompact = oSourceAddress.RangeName
+ GoTo Finally
+End Function &apos; SFDocuments.SF_Calc.CompactLeft
+
+REM -----------------------------------------------------------------------------
+Public Function CompactUp(Optional ByVal Range As Variant _
+ , Optional ByVal WholeRow As Variant _
+ , Optional ByVal FilterFormula As Variant _
+ ) As String
+&apos;&apos;&apos; Delete the rows of a specified range matching a filter expressed as a formula
+&apos;&apos;&apos; applied on each row.
+&apos;&apos;&apos; The deleted cells can span whole rows or be limited to the width of the range
+&apos;&apos;&apos; The execution of the method has no effect on the current selection
+&apos;&apos;&apos; Args:
+&apos;&apos;&apos; Range: the range in which cells have to be erased, as a string
+&apos;&apos;&apos; WholeRow: when True (default = False), erase whole rows
+&apos;&apos;&apos; FilterFormula: the formula to be applied on each row.
+&apos;&apos;&apos; The row is erased when the formula results in True,
+&apos;&apos;&apos; The formula shall probably involve one or more cells of the first row of the range..
+&apos;&apos;&apos; By default, a row is erased when all the cells of the row are empty,
+&apos;&apos;&apos; i.e. suppose the range is &quot;A1:J200&quot; (width = 10) the default value becomes
+&apos;&apos;&apos; &quot;=(COUNTBLANK(A1:J1)=10)&quot;
+&apos;&apos;&apos; Returns:
+&apos;&apos;&apos; A string representing the location of the initial range after compaction,
+&apos;&apos;&apos; or the zero-length string if the whole range has been deleted
+&apos;&apos;&apos; Examples:
+&apos;&apos;&apos; newrange = oDoc.CompactUp(&quot;SheetX.G1:L10&quot;) &apos; All empty rows of the range are suppressed
+&apos;&apos;&apos; newrange = oDoc.CompactUp(&quot;SheetX.G1:L10&quot;, WholeRow := True, FilterFormula := &quot;=(G1=&quot;&quot;X&quot;&quot;)&quot;)
+&apos;&apos;&apos; &apos; The rows having a &quot;X&quot; in column G are completely suppressed
+
+Dim sCompact As String &apos; Return value
+Dim oSourceAddress As Object &apos; Alias of Range as _Address
+Dim lLastCol As Long &apos; Last used column number in the sheet containing Range
+Dim sFormulaRange As String &apos; Range, as a string, where the FilterFormula must be stored
+Dim vCompact As Variant &apos; Array of Boolean values indicating which rows should be erased
+Dim lCountDeleted As Long &apos; Count the deleted rows
+Dim lCountToDelete As Long &apos; Count contiguous rows to be deleted at once
+Dim sPartialRange As String &apos; Contiguous rows to be deleted
+Dim i As Long
+
+Const cstThisSub = &quot;SFDocuments.Calc.CompactUp&quot;
+Const cstSubArgs = &quot;Range, [WholeRow=False], [FilterFormula=&quot;&quot;&quot;&quot;]&quot;
+
+ If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
+ sCompact = &quot;&quot;
+
+Check:
+ If IsMissing(WholeRow) Or IsEmpty(WholeRow) Then WholeRow = False
+ If IsMissing(FilterFormula) Or IsEmpty(FilterFormula) Then FilterFormula = &quot;&quot;
+ If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
+ If Not _IsStillAlive(True) Then GoTo Finally
+ If Not ScriptForge.SF_Utils._Validate(Range, &quot;Range&quot;, V_STRING) Then GoTo Finally
+ If Not ScriptForge.SF_Utils._Validate(WholeRow, &quot;WholeRow&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
+ If Not ScriptForge.SF_Utils._Validate(FilterFormula, &quot;FilterFormula&quot;, V_STRING) Then GoTo Finally
+ End If
+
+Try:
+ Set oSourceAddress = _ParseAddress(Range)
+
+ With oSourceAddress
+
+ &apos; Set the default formula =&gt; all cells are blank
+ If FilterFormula = &quot;&quot; Then FilterFormula = Printf(&quot;=(COUNTBLANK(%C1%R1:%C2%R1)-&quot; &amp; .Width &amp; &quot;=0)&quot;, Range)
+ &apos; Compute the range where to apply the formula
+ lLastCol = LastColumn(.SheetName)
+ sFormulaRange = Offset(Range, , lLastCol - .XCellRange.RangeAddress.StartRow + 1, , 1)
+ SetFormula(sFormulaRange, FilterFormula)
+ &apos; Get the rows to compact: 0 = False, 1 = True
+ vCompact = GetValue(sFormulaRange)
+ ClearAll(sFormulaRange)
+
+ &apos; Iterates from the last to the first row of the range and remove the rows that match the filter
+ &apos; by groups of contiguous rows
+ lCountDeleted = 0
+ lCountToDelete = 0
+ For i = UBound(vCompact) To 0 Step -1
+ If vCompact(i) = 1 Then lCountToDelete = lCountToDelete + 1
+ If i &gt; 0 And vCompact(i) = 1 Then
+ &apos; Do nothing
+ ElseIf lCountToDelete &gt; 0 Then &apos; The current row must be kept but rows below must be removed
+ &apos; Do not forget when the 1st row must be removed
+ sPartialRange = Offset(Range, Iif(i = 0 And vCompact(i) = 1, 0, i + 1), , lCountToDelete)
+ ShiftUp(sPartialRange, WholeRow)
+ lCountDeleted = lCountDeleted + lCountToDelete
+ lCountToDelete = 0
+ End If
+ Next i
+
+ &apos; Compute the final range position
+ If lCountDeleted &lt; .Height Then sCompact = Offset(Range, 0, 0, .Height - lCountDeleted)
+
+ &apos; Push downwards the cells that migrated upwards irrelevantly
+ If Not WholeRow Then
+ If Len(sCompact) &gt; 0 Then
+ sPartialRange = Offset(sCompact, .Height - lCountDeleted, 0, lCountDeleted)
+ Else
+ sPartialRange = .RangeName
+ End If
+ ShiftDown(sPartialRange, WholeRow := False)
+ End If
+
+ End With
+
+Finally:
+ CompactUp = sCompact
+ ScriptForge.SF_Utils._ExitFunction(cstThisSub)
+ Exit Function
+Catch:
+ &apos; When error, return the original range
+ If Not IsNull(oSourceAddress) Then sCompact = oSourceAddress.RangeName
+ GoTo Finally
+End Function &apos; SFDocuments.SF_Calc.CompactUp
+
+REM -----------------------------------------------------------------------------
Public Function CopySheet(Optional ByVal SheetName As Variant _
, Optional ByVal NewName As Variant _
, Optional ByVal BeforeSheet As Variant _
@@ -1925,7 +2141,7 @@ Public Function Offset(Optional ByRef Range As Variant _
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; OFFSETADDRESSERROR The computed range of cells falls beyond the sheet boundaries
&apos;&apos;&apos; Examples:
-&apos;&apos;&apos; oDoc.Offset(&quot;A1&quot;, 2, 2) &apos; &quot;&apos;SheetX&apos;.$C$3&quot; (A1 moved by two rows and two columns down)
+&apos;&apos;&apos; oDoc.Offset(&quot;A1&quot;, 2, 2) &apos; &quot;&apos;SheetX&apos;.$C$3&quot; (A1 moved by two rows and two columns down)
&apos;&apos;&apos; oDoc.Offset(&quot;A1&quot;, 2, 2, 5, 6) &apos; &quot;&apos;SheetX&apos;.$C$3:$H$7&quot;
Dim sOffset As String &apos; Return value
@@ -2727,6 +2943,7 @@ Check:
Try:
Set oSourceAddress = _ParseAddress(Range)
+ Set _LastParsedAddress = Nothing &apos; Range will be erased. Force re-parsing next time
With oSourceAddress
@@ -2889,6 +3106,7 @@ Check:
Try:
Set oSourceAddress = _ParseAddress(Range)
+ Set _LastParsedAddress = Nothing &apos; Range will be erased. Force re-parsing next time
With oSourceAddress