Refactoring

This commit is contained in:
Sergey Chebotar 2022-01-09 10:37:25 +03:00
parent 8672fa8f6b
commit 762127a4aa
15 changed files with 301 additions and 567 deletions

View File

@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.0.32014.148 VisualStudioVersion = 17.0.32014.148
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RehauSku.Assist", "RehauSku.Assist.csproj", "{18A2FF67-0E46-4A86-B872-29F2B3F23ADF}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RehauSku.Assist", "src\RehauSku.Assist.csproj", "{18A2FF67-0E46-4A86-B872-29F2B3F23ADF}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

@ -1,46 +0,0 @@
namespace RehauSku.Forms
{
partial class SettingsForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// SettingsForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Name = "SettingsForm";
this.Text = "SettingsForm";
this.ResumeLayout(false);
}
#endregion
}
}

View File

@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace RehauSku.Forms
{
public partial class SettingsForm : Form
{
public SettingsForm()
{
InitializeComponent();
}
}
}

View File

@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,60 @@
using ExcelDna.Integration;
using Microsoft.Office.Interop.Excel;
using System;
using System.Collections.Generic;
namespace RehauSku.PriceListTools
{
internal abstract class AbstractPriceListTool
{
protected private Application ExcelApp;
protected private PriceList NewPriceList;
protected private List<PriceList> sourcePriceLists;
public AbstractPriceListTool()
{
ExcelApp = (Application)ExcelDnaUtil.Application;
sourcePriceLists = new List<PriceList>();
}
public void OpenNewPrice(string path)
{
Workbook wb = ExcelApp.Workbooks.Open(path);
try
{
NewPriceList = new PriceList(wb);
if (NewPriceList.Sheets.Count == 0)
throw new ArgumentException($"Не найдены листы с артикулами в {wb.Name}");
if (NewPriceList.OfferSheet == null)
throw new ArgumentException($"Нет листа для коммерческого предложения в {wb.Name}");
}
catch (Exception ex)
{
wb.Close();
throw ex;
}
}
public virtual void GetSource(string[] files)
{
ExcelApp.ScreenUpdating = false;
foreach (string file in files)
{
Workbook wb = ExcelApp.Workbooks.Open(file);
PriceList priceList = new PriceList(wb);
sourcePriceLists.Add(priceList);
wb.Close();
}
ExcelApp.ScreenUpdating = true;
}
public virtual void FillPriceList()
{
throw new NotImplementedException();
}
}
}

View File

@ -1,95 +1,74 @@
using ExcelDna.Integration; using Microsoft.Office.Interop.Excel;
using Microsoft.Office.Interop.Excel;
using System; using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace RehauSku.PriceListTools namespace RehauSku.PriceListTools
{ {
class CombineTool : ConjoinTool, IDisposable, IConjoinTool internal class CombineTool : AbstractPriceListTool, IDisposable
{ {
private Dictionary<string, double>[] SkuAmount { get; set; } public override void FillPriceList()
private string[] FileNames { get; set; }
public CombineTool()
{ {
ExcelApp = (Application)ExcelDnaUtil.Application; PriceListSheet offer = NewPriceList.OfferSheet;
} offer.Sheet.Activate();
public void CollectSkuAmount(string[] files) int exportedValues = 0;
int exportedLists = 0;
foreach (var priceList in sourcePriceLists)
{ {
FileNames = files.Select(x => Path.GetFileNameWithoutExtension(x)).ToArray(); foreach (var sheet in priceList.Sheets)
SkuAmount = new Dictionary<string, double>[files.Length];
ExcelApp.ScreenUpdating = false;
for (int i = 0; i < files.Length; i++)
{ {
Workbook wb = ExcelApp.Workbooks.Open(files[i]); if (sheet.SkuAmount.Count == 0)
continue;
try offer.Sheet.Columns[offer.amountColumnNumber]
.EntireColumn
.Insert(XlInsertShiftDirection.xlShiftToRight, XlInsertFormatOrigin.xlFormatFromRightOrBelow);
exportedLists++;
foreach (var kvp in sheet.SkuAmount)
{ {
PriceList priceList = new PriceList(wb); Range cell = offer.Sheet.Columns[offer.skuColumnNumber].Find(kvp.Key);
SkuAmount[i] = new Dictionary<string, double>();
SkuAmount[i].AddValuesFromPriceList(priceList);
}
catch (Exception ex) if (cell == null)
{ {
System.Windows.Forms.MessageBox.Show System.Windows.Forms.MessageBox.Show
($"{wb.Name} не является файлом прайс-листа \n\n {ex.Message}", ($"Артикул {kvp.Key} отсутствует в таблице заказов {RegistryUtil.PriceListPath}",
"Неверный файл прайс-листа!", "Отсутствует позиция в конечной таблице заказов",
System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error); System.Windows.Forms.MessageBoxIcon.Information);
} }
finally else
{ {
wb.Close(); offer.Sheet.Cells[cell.Row, offer.amountColumnNumber].Value2 = kvp.Value;
Range sumCell = offer.Sheet.Cells[cell.Row, offer.amountColumnNumber + exportedLists];
if (sumCell.Value2 == null)
sumCell.Value2 = kvp.Value;
else
sumCell.Value2 += kvp.Value;
exportedValues++;
}
offer.Sheet.Cells[offer.headerRowNumber, offer.amountColumnNumber].Value2 = $"{priceList.Name}\n{sheet.Name}";
}
} }
} }
ExcelApp.ScreenUpdating = true; AutoFilter filter = offer.Sheet.AutoFilter;
} int firstFilterColumn = filter.Range.Column;
public void ExportToFile(string exportFile) filter.Range.AutoFilter(offer.amountColumnNumber - firstFilterColumn + 1 + exportedLists, "<>");
{ offer.Sheet.Range["A1"].Activate();
if (SkuAmount.Sum(d => d.Count) < 1)
{
return;
}
Workbook wb = ExcelApp.Workbooks.Open(exportFile); offer.Sheet.Application.StatusBar = $"Экспортировано {exportedValues} строк из {sourcePriceLists.Count} файлов";
PriceList priceList;
try
{
priceList = new PriceList(wb);
priceList.FillWithValues(SkuAmount, FileNames);
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show
($"{RegistryUtil.PriceListPath} не является файлом прайс-листа \n\n {ex.Message}",
"Неверный файл прайс-листа!",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
wb.Close();
}
} }
public void Dispose() public void Dispose()
{ {
//Dispose(true);
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
//protected virtual void Dispose(bool disposing)
//{
//}
} }
} }

View File

@ -1,9 +0,0 @@
using Microsoft.Office.Interop.Excel;
namespace RehauSku.PriceListTools
{
internal class ConjoinTool
{
protected Application ExcelApp;
}
}

View File

@ -6,28 +6,25 @@ using System.Collections.Generic;
namespace RehauSku.PriceListTools namespace RehauSku.PriceListTools
{ {
class ExportTool : IDisposable internal class ExportTool : AbstractPriceListTool, IDisposable
{ {
private Application ExcelApp;
private Dictionary<string, double> SkuAmount { get; set; } private Dictionary<string, double> SkuAmount { get; set; }
private Range Selection { get; set; } private Range Selection;
public ExportTool() public ExportTool()
{ {
this.ExcelApp = (Application)ExcelDnaUtil.Application; ExcelApp = (Application)ExcelDnaUtil.Application;
Selection = ExcelApp.Selection; Selection = ExcelApp.Selection;
if (IsRangeValid())
_FillSkuAmountDict();
} }
public bool IsRangeValid() public override void GetSource(string[] files)
{ {
return Selection != null && if (Selection != null && Selection.Columns.Count == 2)
Selection.Columns.Count == 2; FillSkuAmountDict();
else throw new Exception("Неверный диапазон");
} }
private void _FillSkuAmountDict() private void FillSkuAmountDict()
{ {
object[,] cells = Selection.Value2; object[,] cells = Selection.Value2;
SkuAmount = new Dictionary<string, double>(); SkuAmount = new Dictionary<string, double>();
@ -72,44 +69,53 @@ namespace RehauSku.PriceListTools
} }
} }
public void ExportToNewFile() public override void FillPriceList()
{ {
if (SkuAmount.Count < 1) if (SkuAmount.Count < 1) return;
PriceListSheet offer = NewPriceList.OfferSheet;
offer.Sheet.Activate();
int exportedValues = 0;
foreach (var kvp in SkuAmount)
{ {
return; Range cell = offer.Sheet.Columns[offer.skuColumnNumber].Find(kvp.Key);
}
string exportFile = PriceListUtil.CreateNewExportFile(); if (cell == null)
Workbook wb = ExcelApp.Workbooks.Open(exportFile);
try
{
PriceList priceList = new PriceList(wb);
priceList.FillWithValues(SkuAmount);
}
catch(Exception ex)
{ {
System.Windows.Forms.MessageBox.Show System.Windows.Forms.MessageBox.Show
($"{RegistryUtil.PriceListPath} не является файлом прайс-листа \n\n {ex.Message}", ($"Артикул {kvp.Key} отсутствует в таблице заказов {RegistryUtil.PriceListPath}",
"Неверный файл прайс-листа!", "Отсутствует позиция в конечной таблице заказов",
System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error); System.Windows.Forms.MessageBoxIcon.Information);
wb.Close();
} }
else
{
Range sumCell = offer.Sheet.Cells[cell.Row, offer.amountColumnNumber];
if (sumCell.Value2 == null)
sumCell.Value2 = kvp.Value;
else
sumCell.Value2 += kvp.Value;
exportedValues++;
}
}
AutoFilter filter = offer.Sheet.AutoFilter;
int firstFilterColumn = filter.Range.Column;
filter.Range.AutoFilter(offer.amountColumnNumber - firstFilterColumn + 1, "<>");
offer.Sheet.Range["A1"].Activate();
offer.Sheet.Application.StatusBar = $"Экспортировано {exportedValues} строк из {SkuAmount.Count}";
} }
public void Dispose() public void Dispose()
{ {
Dispose(true);
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
protected virtual void Dispose(bool disposing)
{
}
} }
} }

View File

@ -1,8 +0,0 @@
namespace RehauSku.PriceListTools
{
internal interface IConjoinTool
{
void CollectSkuAmount(string[] files);
void ExportToFile(string exportFile);
}
}

View File

@ -1,87 +1,63 @@
using ExcelDna.Integration; using Microsoft.Office.Interop.Excel;
using Microsoft.Office.Interop.Excel;
using System; using System;
using System.Collections.Generic;
namespace RehauSku.PriceListTools namespace RehauSku.PriceListTools
{ {
class MergeTool : ConjoinTool, IDisposable, IConjoinTool internal class MergeTool : AbstractPriceListTool, IDisposable
{ {
private Dictionary<string, double> SkuAmount { get; set; } public override void FillPriceList()
{
PriceListSheet offer = NewPriceList.OfferSheet;
offer.Sheet.Activate();
public MergeTool() int exportedValues = 0;
{
ExcelApp = (Application)ExcelDnaUtil.Application;
SkuAmount = new Dictionary<string, double>();
}
public void CollectSkuAmount(string[] files) foreach (var priceList in sourcePriceLists)
{ {
ExcelApp.ScreenUpdating = false; foreach (var sheet in priceList.Sheets)
foreach (string file in files)
{ {
Workbook wb = ExcelApp.Workbooks.Open(file); if (sheet.SkuAmount.Count == 0)
continue;
try foreach (var kvp in sheet.SkuAmount)
{ {
PriceList priceList = new PriceList(wb); Range cell = offer.Sheet.Columns[offer.skuColumnNumber].Find(kvp.Key);
SkuAmount.AddValuesFromPriceList(priceList);
}
catch (Exception ex) if (cell == null)
{ {
System.Windows.Forms.MessageBox.Show System.Windows.Forms.MessageBox.Show
($"{wb.Name} не является файлом прайс-листа \n\n {ex.Message}", ($"Артикул {kvp.Key} отсутствует в таблице заказов {RegistryUtil.PriceListPath}",
"Неверный файл прайс-листа!", "Отсутствует позиция в конечной таблице заказов",
System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error); System.Windows.Forms.MessageBoxIcon.Information);
} }
finally else
{ {
wb.Close(); Range sumCell = offer.Sheet.Cells[cell.Row, offer.amountColumnNumber];
if (sumCell.Value2 == null)
sumCell.Value2 = kvp.Value;
else
sumCell.Value2 += kvp.Value;
exportedValues++;
}
} }
} }
ExcelApp.ScreenUpdating = true;
} }
public void ExportToFile(string exportFile) AutoFilter filter = offer.Sheet.AutoFilter;
{ int firstFilterColumn = filter.Range.Column;
if (SkuAmount.Count < 1)
{
return;
}
Workbook wb = ExcelApp.Workbooks.Open(exportFile); filter.Range.AutoFilter(offer.amountColumnNumber - firstFilterColumn + 1, "<>");
PriceList priceList; offer.Sheet.Range["A1"].Activate();
offer.Sheet.Application.StatusBar = $"Экспортировано {exportedValues} строк из {sourcePriceLists.Count} файлов";
try
{
priceList = new PriceList(wb);
priceList.FillWithValues(SkuAmount);
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show
($"{RegistryUtil.PriceListPath} не является файлом прайс-листа \n\n {ex.Message}",
"Неверный файл прайс-листа!",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
wb.Close();
}
} }
public void Dispose() public void Dispose()
{ {
Dispose(true);
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
protected virtual void Dispose(bool disposing)
{
}
} }
} }

View File

@ -1,146 +1,41 @@
using Microsoft.Office.Interop.Excel; using Microsoft.Office.Interop.Excel;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
namespace RehauSku.PriceListTools namespace RehauSku.PriceListTools
{ {
class PriceList internal class PriceList
{ {
public readonly Workbook Workbook; public readonly string Name;
public readonly PriceListSheet OfferSheet; public readonly PriceListSheet OfferSheet;
public readonly PriceListSheet ActiveSheet; public List<PriceListSheet> Sheets { get; private set; }
private const string amountHeader = "Кол-во";
private const string skuHeader = "Актуальный материал";
private const string offerSheetHeader = "КП"; private const string offerSheetHeader = "КП";
public PriceList(Workbook workbook) public PriceList(Workbook workbook)
{ {
Workbook = workbook; Name = workbook.Name;
OfferSheet = new PriceListSheet(workbook.Sheets[offerSheetHeader]); Sheets = new List<PriceListSheet>();
Worksheet active = workbook.ActiveSheet; foreach (Worksheet worksheet in workbook.Sheets)
if (active.Name == offerSheetHeader)
ActiveSheet = OfferSheet;
else
ActiveSheet = new PriceListSheet(active);
}
public void FillWithValues(Dictionary<string, double> values)
{ {
Worksheet ws = OfferSheet.sheet; PriceListSheet priceListSheet = new PriceListSheet(worksheet);
ws.Activate();
int amountColumn = OfferSheet.amountColumn.Value; if (priceListSheet.FillSkuAmount())
int skuColumn = OfferSheet.skuColumn.Value; Sheets.Add(priceListSheet);
int exportedValues = 0; }
foreach (KeyValuePair<string, double> kvp in values) OfferSheet = Sheets.Where(s => s.Name == offerSheetHeader).FirstOrDefault();
}
public static string CreateNewFile()
{ {
Range cell = ws.Columns[skuColumn].Find(kvp.Key); string fileExtension = Path.GetExtension(RegistryUtil.PriceListPath);
string path = Path.GetTempFileName() + fileExtension;
if (cell == null) File.Copy(RegistryUtil.PriceListPath, path);
{ return path;
System.Windows.Forms.MessageBox.Show
($"Артикул {kvp.Key} отсутствует в таблице заказов {RegistryUtil.PriceListPath}",
"Отсутствует позиция в конечной таблице заказов",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Information);
}
else
{
ws.Cells[cell.Row, amountColumn].Value = kvp.Value;
exportedValues++;
}
}
AutoFilter filter = ws.AutoFilter;
int firstFilterColumn = filter.Range.Column;
filter.Range.AutoFilter(amountColumn - firstFilterColumn + 1, "<>");
ws.Range["A1"].Activate();
ws.Application.StatusBar = $"Экспортировано {exportedValues} строк из {values.Count}";
}
public void FillWithValues(Dictionary<string, double>[] values, string[] filenames)
{
Worksheet ws = OfferSheet.sheet;
ws.Activate();
int amountColumn = OfferSheet.amountColumn.Value;
int skuColumn = OfferSheet.skuColumn.Value;
int headerColumn = OfferSheet.headerRow.Value;
int exportedValues = 0;
for (int i = 0; i < values.Length; i++)
{
ws.Columns[amountColumn]
.EntireColumn
.Insert(XlInsertShiftDirection.xlShiftToRight, XlInsertFormatOrigin.xlFormatFromRightOrBelow);
foreach (var kvp in values[i])
{
Range cell = ws.Columns[skuColumn].Find(kvp.Key);
if (cell == null)
{
System.Windows.Forms.MessageBox.Show
($"Артикул {kvp.Key} отсутствует в таблице заказов {RegistryUtil.PriceListPath}",
"Отсутствует позиция в конечной таблице заказов",
System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Information);
}
else
{
ws.Cells[cell.Row, amountColumn].Value2 = kvp.Value;
Range sumCell = ws.Cells[cell.Row, amountColumn + i + 1];
if (sumCell.Value2 == null)
sumCell.Value2 = kvp.Value;
else
sumCell.Value2 += kvp.Value;
exportedValues++;
}
}
ws.Cells[headerColumn, amountColumn].Value2 = filenames[i];
}
AutoFilter filter = ws.AutoFilter;
int firstFilterColumn = filter.Range.Column;
filter.Range.AutoFilter(amountColumn - firstFilterColumn + 1 + values.Length, "<>");
ws.Range["A1"].Activate();
ws.Application.StatusBar = $"Экспортировано {exportedValues} строк из {values.Sum(x => x.Count)}";
}
public class PriceListSheet
{
public readonly Worksheet sheet;
public readonly int? headerRow;
public readonly int? skuColumn;
public readonly int? amountColumn;
public object[,] skuCells;
public object[,] amountCells;
public PriceListSheet(Worksheet sheet)
{
this.sheet = sheet;
headerRow = sheet.Cells.Find(amountHeader).Row;
amountColumn = sheet.Cells.Find(amountHeader).Column;
skuColumn = sheet.Cells.Find(skuHeader).Column;
amountCells = sheet.Columns[amountColumn].Value2;
skuCells = sheet.Columns[skuColumn].Value2;
}
} }
} }
} }

View File

@ -0,0 +1,64 @@
using Microsoft.Office.Interop.Excel;
using System.Collections.Generic;
namespace RehauSku.PriceListTools
{
internal class PriceListSheet
{
private const string amountHeader = "Кол-во";
private const string skuHeader = "Актуальный материал";
public readonly Worksheet Sheet;
public readonly string Name;
public Dictionary<string, double> SkuAmount { get; private set; }
public int headerRowNumber { get; private set; }
public int amountColumnNumber { get; private set; }
public int skuColumnNumber { get; private set; }
public PriceListSheet(Worksheet sheet)
{
Sheet = sheet;
Name = sheet.Name;
SkuAmount = new Dictionary<string, double>();
FillSkuAmount();
}
public bool FillSkuAmount()
{
Range amountCell = Sheet.Cells.Find(amountHeader);
Range skuCell = Sheet.Cells.Find(skuHeader);
if (amountCell == null || skuCell == null)
{
Sheet.Application.StatusBar = $"Лист {Name} не распознан";
return false;
}
headerRowNumber = amountCell.Row;
skuColumnNumber = skuCell.Column;
amountColumnNumber = amountCell.Column;
object[,] amountColumn = Sheet.Columns[amountColumnNumber].Value2;
object[,] skuColumn = Sheet.Columns[skuColumnNumber].Value2;
for (int row = headerRowNumber + 1; row < amountColumn.GetLength(0); row++)
{
object amount = amountColumn[row, 1];
object sku = skuColumn[row, 1];
if (amount != null && (double)amount != 0)
{
if (SkuAmount.ContainsKey(sku.ToString()))
SkuAmount[sku.ToString()] += (double)amount;
else
SkuAmount.Add(sku.ToString(), (double)amount);
}
}
return true;
}
}
}

View File

@ -1,41 +0,0 @@
using System.Collections.Generic;
using System.IO;
namespace RehauSku.PriceListTools
{
static class PriceListUtil
{
public static string CreateNewExportFile()
{
string fileExtension = Path.GetExtension(RegistryUtil.PriceListPath);
string path = Path.GetTempFileName() + fileExtension;
File.Copy(RegistryUtil.PriceListPath, path);
return path;
}
public static void AddValuesFromPriceList(this Dictionary<string, double> SkuAmount, PriceList priceList)
{
object[,] amountCells = priceList.ActiveSheet.amountCells;
object[,] skuCells = priceList.ActiveSheet.skuCells;
for (int row = priceList.ActiveSheet.headerRow.Value + 1; row < amountCells.GetLength(0); row++)
{
object amount = amountCells[row, 1];
object sku = skuCells[row, 1];
if (amount != null && (double)amount != 0)
{
if (SkuAmount.ContainsKey(sku.ToString()))
{
SkuAmount[sku.ToString()] += (double)amount;
}
else
SkuAmount.Add(sku.ToString(), (double)amount);
}
}
}
}
}

View File

@ -107,11 +107,10 @@
<Compile Include="Assistant\RequestModifier.cs" /> <Compile Include="Assistant\RequestModifier.cs" />
<Compile Include="Assistant\SkuExtensions.cs" /> <Compile Include="Assistant\SkuExtensions.cs" />
<Compile Include="PriceListTools\CombineTool.cs" /> <Compile Include="PriceListTools\CombineTool.cs" />
<Compile Include="PriceListTools\ConjoinTool.cs" /> <Compile Include="PriceListTools\AbstractPriceListTool.cs" />
<Compile Include="PriceListTools\IConjoinTool.cs" />
<Compile Include="PriceListTools\MergeTool.cs" /> <Compile Include="PriceListTools\MergeTool.cs" />
<Compile Include="PriceListTools\PriceList.cs" /> <Compile Include="PriceListTools\PriceList.cs" />
<Compile Include="PriceListTools\PriceListUtil.cs" /> <Compile Include="PriceListTools\PriceListSheet.cs" />
<Compile Include="Ribbon\RibbonController.cs" /> <Compile Include="Ribbon\RibbonController.cs" />
<Compile Include="Assistant\HttpClientUtil.cs" /> <Compile Include="Assistant\HttpClientUtil.cs" />
<Compile Include="Assistant\StoreResponse.cs" /> <Compile Include="Assistant\StoreResponse.cs" />
@ -121,12 +120,6 @@
<Compile Include="AddIn\Functions.cs" /> <Compile Include="AddIn\Functions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Assistant\SkuAssist.cs" /> <Compile Include="Assistant\SkuAssist.cs" />
<Compile Include="Forms\SettingsForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\SettingsForm.Designer.cs">
<DependentUpon>SettingsForm.cs</DependentUpon>
</Compile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="app.config" /> <None Include="app.config" />

View File

@ -3,6 +3,7 @@ using System.Windows.Forms;
using ExcelDna.Integration.CustomUI; using ExcelDna.Integration.CustomUI;
using RehauSku.PriceListTools; using RehauSku.PriceListTools;
using RehauSku.Forms; using RehauSku.Forms;
using System;
namespace RehauSku.Ribbon namespace RehauSku.Ribbon
{ {
@ -24,7 +25,7 @@ namespace RehauSku.Ribbon
</menu> </menu>
</group> </group>
<group id='rausettings' label='Настройки'> <group id='rausettings' label='Настройки'>
<button id='setPriceList' label='Файл прайс-листа' size='normal' imageMso='CurrentViewSettings' onAction='OnSetPricePressed'/> <button id='setPriceList' label='Файл прайс-листа' size='large' imageMso='CurrentViewSettings' onAction='OnSetPricePressed'/>
</group> </group>
</tab> </tab>
</tabs> </tabs>
@ -39,9 +40,10 @@ namespace RehauSku.Ribbon
using (MergeTool mergeTool = new MergeTool()) using (MergeTool mergeTool = new MergeTool())
{ {
string[] files = Dialog.GetMultiplyFiles(); string[] files = Dialog.GetMultiplyFiles();
mergeTool.CollectSkuAmount(files); mergeTool.GetSource(files);
string exportFile = PriceListUtil.CreateNewExportFile(); string exportFile = PriceList.CreateNewFile();
mergeTool.ExportToFile(exportFile); mergeTool.OpenNewPrice(exportFile);
mergeTool.FillPriceList();
} }
} }
@ -50,30 +52,34 @@ namespace RehauSku.Ribbon
using (CombineTool combineTool = new CombineTool()) using (CombineTool combineTool = new CombineTool())
{ {
string[] files = Dialog.GetMultiplyFiles(); string[] files = Dialog.GetMultiplyFiles();
combineTool.CollectSkuAmount(files); combineTool.GetSource(files);
string exportFile = PriceListUtil.CreateNewExportFile(); string exportFile = PriceList.CreateNewFile();
combineTool.ExportToFile(exportFile); combineTool.OpenNewPrice(exportFile);
combineTool.FillPriceList();
} }
} }
public void OnExportPressed(IRibbonControl control) public void OnExportPressed(IRibbonControl control)
{
try
{ {
using (ExportTool exportTool = new ExportTool()) using (ExportTool exportTool = new ExportTool())
{ {
if (!exportTool.IsRangeValid()) exportTool.GetSource(null);
string exportFile = PriceList.CreateNewFile();
exportTool.OpenNewPrice(exportFile);
exportTool.FillPriceList();
}
}
catch (Exception ex)
{ {
MessageBox.Show("Выделен неверный диапазон!", MessageBox.Show(ex.Message,
"Неверный диапазон", "Ошибка",
MessageBoxButtons.OK, MessageBoxButtons.OK,
MessageBoxIcon.Information); MessageBoxIcon.Information);
return; return;
} }
else
{
exportTool.ExportToNewFile();
}
}
} }
public void OnSetPricePressed(IRibbonControl control) public void OnSetPricePressed(IRibbonControl control)