aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--RhSolutions.AddIn/ExcelTable/ExcelColumn.cs47
-rw-r--r--RhSolutions.AddIn/ExcelTable/ExcelColumnEnumerator.cs54
-rw-r--r--RhSolutions.AddIn/ExcelTable/ExcelColumns.cs39
-rw-r--r--RhSolutions.AddIn/ExcelTable/ExcelColumnsEnumerator.cs54
-rw-r--r--RhSolutions.AddIn/ExcelTable/ExcelRow.cs33
-rw-r--r--RhSolutions.AddIn/ExcelTable/ExcelRowEnumerator.cs54
-rw-r--r--RhSolutions.AddIn/ExcelTable/ExcelRows.cs39
-rw-r--r--RhSolutions.AddIn/ExcelTable/ExcelRowsEnumerator.cs55
-rw-r--r--RhSolutions.AddIn/ExcelTable/ExcelTable.cs53
-rw-r--r--RhSolutions.AddIn/ExcelTable/ExcelTableCell.cs24
-rw-r--r--RhSolutions.AddIn/RhSolutions.AddIn.csproj2
-rw-r--r--RhSolutions.Tests/ExcelTablesTests.cs65
-rw-r--r--RhSolutions.Tests/RhSolutions.Tests.csproj3
-rw-r--r--RhSolutions.Tests/TestWorkbooks/ExcelTableTest.xlsxbin0 -> 8987 bytes
-rw-r--r--RhSolutions.Tests/Usings.cs2
-rw-r--r--RhSolutions.Tests/WorkbookValidationTests.cs (renamed from RhSolutions.Tests/RhSolutionsCheckTest.cs)10
16 files changed, 527 insertions, 7 deletions
diff --git a/RhSolutions.AddIn/ExcelTable/ExcelColumn.cs b/RhSolutions.AddIn/ExcelTable/ExcelColumn.cs
new file mode 100644
index 0000000..7d72cd5
--- /dev/null
+++ b/RhSolutions.AddIn/ExcelTable/ExcelColumn.cs
@@ -0,0 +1,47 @@
+using System.Collections;
+
+namespace RhSolutions.ExcelTable;
+
+public sealed class ExcelColumn : ExcelTable, IEnumerable<ExcelTableCell>
+{
+ public string Header
+ {
+ get => Range.Cells[1, 1].Value.ToString();
+ }
+ public int Index
+ {
+ get => Range.Column - ParentTable.Range.Column;
+ }
+ public int Length
+ {
+ get => Range.Rows.Count;
+ }
+
+ public ExcelColumn(Range range, ExcelTable table) : base(range, table)
+ {
+ Range = range;
+ ParentTable = table;
+ }
+
+ public ExcelTableCell this[int index]
+ {
+ get => new(Range.Cells[index + 1, 1], ParentTable);
+ }
+
+ public IEnumerator<ExcelTableCell> GetEnumerator()
+ {
+ return new ExcelColumnEnumerator(Range, ParentTable);
+ }
+
+ IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
+
+
+ public ExcelColumn AddLeft()
+ {
+ Range.EntireColumn
+ .Insert(XlInsertShiftDirection.xlShiftToRight,
+ XlInsertFormatOrigin.xlFormatFromRightOrBelow);
+
+ return ParentTable.Columns[this.Index - 1];
+ }
+}
diff --git a/RhSolutions.AddIn/ExcelTable/ExcelColumnEnumerator.cs b/RhSolutions.AddIn/ExcelTable/ExcelColumnEnumerator.cs
new file mode 100644
index 0000000..c809c18
--- /dev/null
+++ b/RhSolutions.AddIn/ExcelTable/ExcelColumnEnumerator.cs
@@ -0,0 +1,54 @@
+using System.Collections;
+
+namespace RhSolutions.ExcelTable;
+
+public class ExcelColumnEnumerator : IEnumerator<ExcelTableCell>
+{
+ public Range Range { get; }
+ public ExcelTable ParentTable { get; }
+ private int position = 0;
+ object IEnumerator.Current
+ {
+ get
+ {
+ return Current;
+ }
+ }
+
+ public ExcelTableCell Current
+ {
+ get
+ {
+ try
+ {
+ return new ExcelTableCell(Range.Cells[position, 1], ParentTable);
+ }
+ catch (IndexOutOfRangeException)
+ {
+ throw new InvalidOperationException();
+ }
+ }
+ }
+
+ public ExcelColumnEnumerator(Range range, ExcelTable table)
+ {
+ Range = range;
+ ParentTable = table;
+ }
+
+ public bool MoveNext()
+ {
+ position++;
+ return (position <= Range.Rows.Count);
+ }
+
+ public void Reset()
+ {
+ position = 0;
+ }
+
+ public void Dispose()
+ {
+
+ }
+}
diff --git a/RhSolutions.AddIn/ExcelTable/ExcelColumns.cs b/RhSolutions.AddIn/ExcelTable/ExcelColumns.cs
new file mode 100644
index 0000000..4aacd6f
--- /dev/null
+++ b/RhSolutions.AddIn/ExcelTable/ExcelColumns.cs
@@ -0,0 +1,39 @@
+using System.Collections;
+
+namespace RhSolutions.ExcelTable;
+
+public class ExcelColumns : IEnumerable<ExcelColumn>
+{
+ public Range Range { get; }
+ public ExcelTable ParentTable { get; }
+ public int Length
+ {
+ get => Range.Columns.Count;
+ }
+
+ public ExcelColumns(Range range, ExcelTable parentTable)
+ {
+ Range = range;
+ ParentTable = parentTable;
+ }
+
+ public ExcelColumn this[int index]
+ {
+ get
+ {
+ if (index < 0 || index + 1 > Range.Columns.Count)
+ {
+ throw new IndexOutOfRangeException();
+ }
+
+ return new ExcelColumn(Range.Columns[index + 1], ParentTable);
+ }
+ }
+
+ public IEnumerator<ExcelColumn> GetEnumerator()
+ {
+ return new ExcelColumnsEnumerator(Range, ParentTable);
+ }
+
+ IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
+} \ No newline at end of file
diff --git a/RhSolutions.AddIn/ExcelTable/ExcelColumnsEnumerator.cs b/RhSolutions.AddIn/ExcelTable/ExcelColumnsEnumerator.cs
new file mode 100644
index 0000000..8c351e9
--- /dev/null
+++ b/RhSolutions.AddIn/ExcelTable/ExcelColumnsEnumerator.cs
@@ -0,0 +1,54 @@
+using System.Collections;
+
+namespace RhSolutions.ExcelTable;
+
+public class ExcelColumnsEnumerator: IEnumerator<ExcelColumn>
+{
+ public Range Range { get; }
+ public ExcelTable ParentTable { get; }
+ private int position = 0;
+ object IEnumerator.Current
+ {
+ get
+ {
+ return Current;
+ }
+ }
+
+ public ExcelColumn Current
+ {
+ get
+ {
+ try
+ {
+ return new ExcelColumn(Range.Columns[position], ParentTable);
+ }
+ catch (IndexOutOfRangeException)
+ {
+ throw new InvalidOperationException();
+ }
+ }
+ }
+
+ public ExcelColumnsEnumerator(Range range, ExcelTable table)
+ {
+ Range = range;
+ ParentTable = table;
+ }
+
+ public bool MoveNext()
+ {
+ position++;
+ return (position <= Range.Columns.Count);
+ }
+
+ public void Reset()
+ {
+ position = 0;
+ }
+
+ public void Dispose()
+ {
+
+ }
+} \ No newline at end of file
diff --git a/RhSolutions.AddIn/ExcelTable/ExcelRow.cs b/RhSolutions.AddIn/ExcelTable/ExcelRow.cs
new file mode 100644
index 0000000..231fd7c
--- /dev/null
+++ b/RhSolutions.AddIn/ExcelTable/ExcelRow.cs
@@ -0,0 +1,33 @@
+using System.Collections;
+
+namespace RhSolutions.ExcelTable;
+
+public sealed class ExcelRow : ExcelTable, IEnumerable<ExcelTableCell>
+{
+ public int Index
+ {
+ get => Range.Row - ParentTable.Range.Row;
+ }
+ public int Length
+ {
+ get => Range.Columns.Count;
+ }
+
+ public ExcelRow(Range range, ExcelTable table) : base(range, table)
+ {
+ Range = range;
+ ParentTable = table;
+ }
+
+ public ExcelTableCell this[int index]
+ {
+ get => new(Range.Cells[1, index + 1], ParentTable);
+ }
+
+ public IEnumerator<ExcelTableCell> GetEnumerator()
+ {
+ return new ExcelRowEnumerator(Range, ParentTable);
+ }
+
+ IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
+}
diff --git a/RhSolutions.AddIn/ExcelTable/ExcelRowEnumerator.cs b/RhSolutions.AddIn/ExcelTable/ExcelRowEnumerator.cs
new file mode 100644
index 0000000..58f88d8
--- /dev/null
+++ b/RhSolutions.AddIn/ExcelTable/ExcelRowEnumerator.cs
@@ -0,0 +1,54 @@
+using System.Collections;
+
+namespace RhSolutions.ExcelTable;
+
+public class ExcelRowEnumerator : IEnumerator<ExcelTableCell>
+{
+ public Range Range { get; }
+ public ExcelTable ParentTable { get; }
+ private int position = 0;
+ object IEnumerator.Current
+ {
+ get
+ {
+ return Current;
+ }
+ }
+
+ public ExcelTableCell Current
+ {
+ get
+ {
+ try
+ {
+ return new ExcelTableCell(Range.Cells[1, position], ParentTable);
+ }
+ catch (IndexOutOfRangeException)
+ {
+ throw new InvalidOperationException();
+ }
+ }
+ }
+
+ public ExcelRowEnumerator(Range range, ExcelTable parentTable)
+ {
+ Range = range;
+ ParentTable = parentTable;
+ }
+
+ public bool MoveNext()
+ {
+ position++;
+ return (position <= Range.Columns.Count);
+ }
+
+ public void Reset()
+ {
+ position = 0;
+ }
+
+ public void Dispose()
+ {
+
+ }
+} \ No newline at end of file
diff --git a/RhSolutions.AddIn/ExcelTable/ExcelRows.cs b/RhSolutions.AddIn/ExcelTable/ExcelRows.cs
new file mode 100644
index 0000000..44602f0
--- /dev/null
+++ b/RhSolutions.AddIn/ExcelTable/ExcelRows.cs
@@ -0,0 +1,39 @@
+using System.Collections;
+
+namespace RhSolutions.ExcelTable;
+
+public class ExcelRows : IEnumerable<ExcelRow>
+{
+ public Range Range { get; }
+ public ExcelTable ParentTable { get; }
+ public int Length
+ {
+ get => Range.Rows.Count;
+ }
+
+ public ExcelRows(Range range, ExcelTable parentTable)
+ {
+ Range = range;
+ ParentTable = parentTable;
+ }
+
+ public ExcelRow this[int index]
+ {
+ get
+ {
+ if (index < 0 || index + 1 > Range.Rows.Count)
+ {
+ throw new IndexOutOfRangeException();
+ }
+
+ return new ExcelRow(Range.Rows[index + 1], ParentTable);
+ }
+ }
+
+ public IEnumerator<ExcelRow> GetEnumerator()
+ {
+ return new ExcelRowsEnumerator(Range, ParentTable);
+ }
+
+ IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
+}
diff --git a/RhSolutions.AddIn/ExcelTable/ExcelRowsEnumerator.cs b/RhSolutions.AddIn/ExcelTable/ExcelRowsEnumerator.cs
new file mode 100644
index 0000000..e5430d1
--- /dev/null
+++ b/RhSolutions.AddIn/ExcelTable/ExcelRowsEnumerator.cs
@@ -0,0 +1,55 @@
+using System.Collections;
+
+namespace RhSolutions.ExcelTable;
+
+public class ExcelRowsEnumerator : IEnumerator<ExcelRow>
+{
+ public Range Range { get; }
+ public ExcelTable ParentTable { get; }
+ private int position = 0;
+ object IEnumerator.Current
+ {
+ get
+ {
+ return Current;
+ }
+ }
+
+ public ExcelRow Current
+ {
+ get
+ {
+ try
+ {
+ return new ExcelRow(Range.Rows[position], ParentTable);
+ }
+ catch (IndexOutOfRangeException)
+ {
+ throw new InvalidOperationException();
+ }
+ }
+ }
+
+ public ExcelRowsEnumerator(Range range, ExcelTable table)
+ {
+ Range = range;
+ ParentTable = table;
+ }
+
+ public bool MoveNext()
+ {
+ position++;
+ return (position <= Range.Rows.Count);
+ }
+
+ public void Reset()
+ {
+ position = 0;
+ }
+
+ public void Dispose()
+ {
+
+ }
+
+} \ No newline at end of file
diff --git a/RhSolutions.AddIn/ExcelTable/ExcelTable.cs b/RhSolutions.AddIn/ExcelTable/ExcelTable.cs
new file mode 100644
index 0000000..2788036
--- /dev/null
+++ b/RhSolutions.AddIn/ExcelTable/ExcelTable.cs
@@ -0,0 +1,53 @@
+namespace RhSolutions.ExcelTable;
+
+public class ExcelTable
+{
+ public Range Range { get; protected set; }
+ public ExcelTable ParentTable { get; protected set; }
+ public ExcelRows Rows { get; }
+ public ExcelColumns Columns { get; }
+
+ public ExcelTable(Range range)
+ {
+ Range = range;
+ ParentTable = null;
+ Rows = new ExcelRows(Range, this);
+ Columns = new ExcelColumns(Range, this);
+ }
+
+ public ExcelTable(Range range, ExcelTable table)
+ {
+ Range = range;
+ ParentTable = table;
+ Rows = new ExcelRows(Range, this);
+ Columns = new ExcelColumns(Range, this);
+ }
+
+ public ExcelTableCell this[int row, int column]
+ {
+ get => new(Range.Cells[row + 1, column + 1], this);
+ }
+
+ public IEnumerable<ExcelTableCell> Find(object item)
+ {
+ Range firstFound = Range.Find(item);
+ if (firstFound == null)
+ {
+ yield break;
+ }
+
+ Range nextFound = firstFound;
+
+ while (true)
+ {
+ yield return new ExcelTableCell(nextFound, ParentTable ?? this);
+ nextFound = Range.FindNext(nextFound);
+
+ if (nextFound.Row == firstFound.Row
+ && nextFound.Column == firstFound.Column)
+ {
+ yield break;
+ }
+ }
+ }
+}
diff --git a/RhSolutions.AddIn/ExcelTable/ExcelTableCell.cs b/RhSolutions.AddIn/ExcelTable/ExcelTableCell.cs
new file mode 100644
index 0000000..8f742d2
--- /dev/null
+++ b/RhSolutions.AddIn/ExcelTable/ExcelTableCell.cs
@@ -0,0 +1,24 @@
+namespace RhSolutions.ExcelTable;
+
+public sealed class ExcelTableCell : ExcelTable
+{
+ public ExcelRow ParentRow
+ {
+ get => ParentTable.Rows[ParentTable.Range.Row - Range.Row];
+ }
+ public ExcelColumn ParentColumn
+ {
+ get => ParentTable.Columns[ParentTable.Range.Column - Range.Column];
+ }
+ public object Value
+ {
+ get => Range.Cells[1, 1].Value2;
+ set => Range.Cells[1, 1].Value2 = value;
+ }
+
+ public ExcelTableCell(Range range, ExcelTable table) : base(range, table)
+ {
+ Range = range;
+ ParentTable = table;
+ }
+}
diff --git a/RhSolutions.AddIn/RhSolutions.AddIn.csproj b/RhSolutions.AddIn/RhSolutions.AddIn.csproj
index 59173c5..81fcb6a 100644
--- a/RhSolutions.AddIn/RhSolutions.AddIn.csproj
+++ b/RhSolutions.AddIn/RhSolutions.AddIn.csproj
@@ -3,7 +3,7 @@
<TargetFrameworks>net472;net6.0-windows7.0</TargetFrameworks>
<LangVersion>10</LangVersion>
<OutputType>Library</OutputType>
- <RootNamespace>RhSolutions.AddIn</RootNamespace>
+ <RootNamespace>RhSolutions</RootNamespace>
<AssemblyName>RhSolutions.AddIn</AssemblyName>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<UseWindowsForms>true</UseWindowsForms>
diff --git a/RhSolutions.Tests/ExcelTablesTests.cs b/RhSolutions.Tests/ExcelTablesTests.cs
new file mode 100644
index 0000000..3ce71bc
--- /dev/null
+++ b/RhSolutions.Tests/ExcelTablesTests.cs
@@ -0,0 +1,65 @@
+namespace RhSolutions.Tests;
+
+[ExcelTestSettings(OutOfProcess = true, Workbook = @"TestWorkbooks\ExcelTableTest.xlsx")]
+public class ExcelTablesTests : IDisposable
+{
+ ExcelTable.ExcelTable table;
+
+ public ExcelTablesTests()
+ {
+ Util.Application.Workbooks.Add();
+
+ Worksheet worksheet = Util.Workbook.Sheets[1];
+ Range range = worksheet.Range["E7:G9"];
+ table = new(range);
+ }
+
+ [ExcelFact]
+ public void CanReadExcelTable()
+ {
+ Assert.Equal(3, table.Columns.Where(c => c.Header.StartsWith("Столбец")).Count());
+ Assert.Equal("Столбец 1", table.Rows.First()[0].Value);
+ Assert.Equal("Столбец 2", table[0, 1].Value);
+ Assert.Equal(123d, table[1, 1].Value);
+ Assert.Null(table[1, 2].Value);
+ }
+
+ [ExcelFact]
+ public void CanModifyTableCells()
+ {
+ table[2, 1].Value = 1;
+ table[1, 1].Value = (double)table[1, 1].Value + 123;
+ Assert.Equal(1d, table[2, 1].Value);
+ Assert.Equal(246d, table[1, 1].Value);
+ }
+
+ [ExcelFact]
+ public void CanFindInTable()
+ {
+ table[2, 0].Value = "Find!";
+ table[2, 1].Value = "Find this!";
+ table[2, 2].Value = "Find that!";
+
+
+ var cells = table.Find("Find");
+ Assert.Collection(cells, item => Assert.Equal("Find!", item.Value),
+ item => Assert.Equal("Find this!", item.Value),
+ item => Assert.Equal("Find that!", item.Value));
+ Assert.Equal(0, table.Find("Значение").First().ParentColumn.Index);
+ Assert.Equal(3, table.Rows[2].Find("Find").Count());
+ Assert.Empty(table.Columns[1].Find("Пусто"));
+ }
+
+ [ExcelFact]
+ public void CanAddColumns()
+ {
+ int originalCount = table.Columns.Count();
+ table.Columns[1].AddLeft();
+ Assert.Equal(originalCount + 1, table.Columns.Count());
+ }
+
+ public void Dispose()
+ {
+ Util.Application.ActiveWindow.Close(SaveChanges: false);
+ }
+}
diff --git a/RhSolutions.Tests/RhSolutions.Tests.csproj b/RhSolutions.Tests/RhSolutions.Tests.csproj
index aeb9c9e..9410802 100644
--- a/RhSolutions.Tests/RhSolutions.Tests.csproj
+++ b/RhSolutions.Tests/RhSolutions.Tests.csproj
@@ -24,6 +24,9 @@
<None Update="TestWorkbooks\EmptyWorkbook.xlsx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
+ <None Update="TestWorkbooks\ExcelTableTest.xlsx">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
</ItemGroup>
</Project>
diff --git a/RhSolutions.Tests/TestWorkbooks/ExcelTableTest.xlsx b/RhSolutions.Tests/TestWorkbooks/ExcelTableTest.xlsx
new file mode 100644
index 0000000..da4cf0b
--- /dev/null
+++ b/RhSolutions.Tests/TestWorkbooks/ExcelTableTest.xlsx
Binary files differ
diff --git a/RhSolutions.Tests/Usings.cs b/RhSolutions.Tests/Usings.cs
index 74130ca..4b95659 100644
--- a/RhSolutions.Tests/Usings.cs
+++ b/RhSolutions.Tests/Usings.cs
@@ -1,5 +1,5 @@
global using Xunit;
global using Microsoft.Office.Interop.Excel;
global using ExcelDna.Testing;
-global using RhSolutions.Models;
+global using RhSolutions.ExcelTable;
global using RhSolutions.Services;
diff --git a/RhSolutions.Tests/RhSolutionsCheckTest.cs b/RhSolutions.Tests/WorkbookValidationTests.cs
index f4d1317..aec7139 100644
--- a/RhSolutions.Tests/RhSolutionsCheckTest.cs
+++ b/RhSolutions.Tests/WorkbookValidationTests.cs
@@ -1,9 +1,9 @@
namespace RhSolutions.Tests;
[ExcelTestSettings(OutOfProcess = true)]
-public class WorkbookCheck : IDisposable
+public class WorkbookValidationTests : IDisposable
{
- public WorkbookCheck()
+ public WorkbookValidationTests()
{
Util.Application.Workbooks.Add();
}
@@ -11,7 +11,7 @@ public class WorkbookCheck : IDisposable
[ExcelFact(Workbook = @"TestWorkbooks\EmptyTestTable.xlsx")]
public void WorksheetIsCorrect()
{
- Worksheet worksheet= Util.Workbook.Sheets[1];
+ Worksheet worksheet = Util.Workbook.Sheets[1];
Assert.True(worksheet.IsRehauSource());
}
@@ -24,6 +24,6 @@ public class WorkbookCheck : IDisposable
public void Dispose()
{
- Util.Application.ActiveWorkbook.Close(SaveChanges: false);
+ Util.Application.ActiveWindow.Close(SaveChanges: false);
}
-}
+} \ No newline at end of file