diff --git a/RehauSku.Assist.csproj b/RehauSku.Assist.csproj index 0088743..8783034 100644 --- a/RehauSku.Assist.csproj +++ b/RehauSku.Assist.csproj @@ -100,25 +100,28 @@ - + - + + + + - + - + Form - + SettingsForm.cs @@ -128,6 +131,9 @@ + + + diff --git a/Source/AddIn/AddIn.cs b/Source/AddIn/AddIn.cs index 014b607..67cdcc8 100644 --- a/Source/AddIn/AddIn.cs +++ b/Source/AddIn/AddIn.cs @@ -2,6 +2,8 @@ using ExcelDna.IntelliSense; using ExcelDna.Registration; using System.Net.Http; +using System.Runtime.Caching; + namespace RehauSku { @@ -16,10 +18,13 @@ namespace RehauSku public class AddIn : IExcelAddIn { - public static HttpClient httpClient = new HttpClient(); + public static HttpClient httpClient; + public static MemoryCache memoryCache; public void AutoOpen() { + httpClient = new HttpClient(); + memoryCache = new MemoryCache("RehauSku"); RegisterFunctions(); IntelliSenseServer.Install(); RegistryUtil.Initialize(); @@ -29,6 +34,7 @@ namespace RehauSku { IntelliSenseServer.Uninstall(); RegistryUtil.Uninitialize(); + memoryCache.Dispose(); } void RegisterFunctions() diff --git a/Source/AddIn/FileDialog.cs b/Source/AddIn/FileDialog.cs deleted file mode 100644 index a7e2144..0000000 --- a/Source/AddIn/FileDialog.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Windows.Forms; - -namespace RehauSku -{ - static class FileDialog - { - public static string GetFilePath() - { - string filePath = string.Empty; - - using (OpenFileDialog dialog = new OpenFileDialog()) - { - dialog.Filter = "Все файлы (*.*)|*.*"; - - if (dialog.ShowDialog() == DialogResult.OK) - { - filePath = dialog.FileName; - } - } - - return filePath; - } - } -} diff --git a/Source/Assistant/MemoryCacheExtensions.cs b/Source/AddIn/MemoryCacheUtil.cs similarity index 54% rename from Source/Assistant/MemoryCacheExtensions.cs rename to Source/AddIn/MemoryCacheUtil.cs index 7eb1408..1d42e14 100644 --- a/Source/Assistant/MemoryCacheExtensions.cs +++ b/Source/AddIn/MemoryCacheUtil.cs @@ -1,19 +1,20 @@ using System; using System.Runtime.Caching; using System.Threading.Tasks; +using RehauSku.Assistant; -namespace RehauSku.Assistant +namespace RehauSku { - static class MemoryCacheExtensions + static class MemoryCacheUtil { public static bool IsCached(this string request) { - return MemoryCache.Default.Contains(request); + return AddIn.memoryCache.Contains(request); } public static IProduct GetFromCache(this string request) { - return MemoryCache.Default[request] as IProduct; + return AddIn.memoryCache[request] as IProduct; } public static async Task RequestAndCache(this string request) @@ -23,8 +24,14 @@ namespace RehauSku.Assistant if (product == null) return null; - MemoryCache.Default.Add(request, product, DateTime.Now.AddMinutes(10)); + AddIn.memoryCache.Add(request, product, DateTime.Now.AddMinutes(10)); return product; } + + public static void ClearCache() + { + AddIn.memoryCache.Dispose(); + AddIn.memoryCache = new MemoryCache("RehauSku"); + } } } \ No newline at end of file diff --git a/Source/AddIn/RegistryUtil.cs b/Source/AddIn/RegistryUtil.cs index ef1398e..3e7c120 100644 --- a/Source/AddIn/RegistryUtil.cs +++ b/Source/AddIn/RegistryUtil.cs @@ -1,5 +1,7 @@ using Microsoft.Win32; using System.IO; +using RehauSku.Forms; +using System.Windows.Forms; namespace RehauSku { @@ -19,6 +21,7 @@ namespace RehauSku public static void Uninitialize() { _RootKey.Close(); + } public static bool IsPriceListPathEmpty() @@ -32,7 +35,8 @@ namespace RehauSku { if (IsPriceListPathEmpty() || !File.Exists(_priceListPath)) { - string fileName = FileDialog.GetFilePath(); + MessageBox.Show("Прайс-лист отсутствует или неверный файл прайс-листа", "Укажите файл прайс-листа", MessageBoxButtons.OK, MessageBoxIcon.Warning); + string fileName = Dialog.GetFilePath(); _priceListPath = fileName; _RootKey.SetValue("PriceListPath", fileName); return _priceListPath; diff --git a/Source/DataExport/ExportTool.cs b/Source/DataExport/ExportTool.cs deleted file mode 100644 index 8ea65cd..0000000 --- a/Source/DataExport/ExportTool.cs +++ /dev/null @@ -1,129 +0,0 @@ -using ExcelDna.Integration; -using Microsoft.Office.Interop.Excel; -using System; -using System.Collections.Generic; -using System.IO; -using RehauSku.Assistant; - -namespace RehauSku.DataExport -{ - public class ExportTool : IDisposable - { - private Application xlApp; - private Dictionary SkuAmount { get; set; } - private Range Selection { get; set; } - private string CurrentFilePath { get; set; } - - public ExportTool() - { - this.xlApp = (Application)ExcelDnaUtil.Application; - this.CurrentFilePath = xlApp.ActiveWorkbook.FullName; - - _GetSelectedCells(); - } - - private void _GetSelectedCells() - { - Selection = xlApp.Selection; - } - - public bool IsRangeValid() - { - return Selection.Columns.Count == 2; - } - - private void FillSkuAmountDict() - { - object[,] cells = Selection.Value2; - SkuAmount = new Dictionary(); - int rowsCount = Selection.Rows.Count; - - for (int row = 1; row <= rowsCount; row++) - { - if (cells[row, 1] == null || cells[row, 2] == null) - continue; - - string sku = null; - double? amount = null; - - for (int column = 1; column <= 2; column++) - { - object current = cells[row, column]; - - if (current.GetType() == typeof(string) - && ((string)current).IsRehauSku()) - sku = (string)current; - - else if (current.GetType() == typeof(string) - && double.TryParse((string)current, out _)) - amount = double.Parse((string)current); - - else if (current.GetType() == typeof(double)) - amount = (double)current; - } - - if (sku == null || amount == null) - continue; - - if (SkuAmount.ContainsKey(sku)) - SkuAmount[sku] += amount.Value; - else - SkuAmount.Add(sku, amount.Value); - } - } - - public void FillNewPriceList() - { - const string amountHeader = "Кол-во"; - const string skuHeader = "Актуальный материал"; - - FillSkuAmountDict(); - string exportFile = _GetExportFullPath(); - File.Copy(RegistryUtil.PriceListPath, exportFile, true); - - Workbook wb = xlApp.Workbooks.Open(exportFile); - Worksheet ws = wb.Sheets["КП"]; - ws.Activate(); - - int amountColumn = ws.Cells.Find(amountHeader).Column; - int skuColumn = ws.Cells.Find(skuHeader).Column; - - foreach (KeyValuePair kvp in SkuAmount) - { - Range cell = ws.Columns[skuColumn].Find(kvp.Key); - ws.Cells[cell.Row, amountColumn].Value = kvp.Value; - } - - AutoFilter filter = ws.AutoFilter; - int firstFilterColumn = filter.Range.Column; - - filter.Range.AutoFilter(amountColumn - firstFilterColumn + 1, "<>"); - ws.Range["A1"].Activate(); - } - - private string _GetExportFullPath() - { - string fileExtension = Path.GetExtension(RegistryUtil.PriceListPath); - - return Path.GetTempFileName() + fileExtension; - } - - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - - } - } - - class SelectionCheck - { - - } -} - diff --git a/Source/Forms/Dialog.cs b/Source/Forms/Dialog.cs new file mode 100644 index 0000000..1953816 --- /dev/null +++ b/Source/Forms/Dialog.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; +using System.Windows.Forms; + +namespace RehauSku.Forms +{ + static class Dialog + { + public static string GetFilePath() + { + string filePath = string.Empty; + + using (OpenFileDialog dialog = new OpenFileDialog()) + { + dialog.Filter = "Все файлы (*.*)|*.*"; + + if (dialog.ShowDialog() == DialogResult.OK) + { + filePath = dialog.FileName; + } + } + + return filePath; + } + + public static string[] GetMultiplyFiles() + { + List fileNames = new List(); + + using (OpenFileDialog dialog = new OpenFileDialog()) + { + dialog.Filter = "Все файлы (*.*)|*.*"; + dialog.Multiselect = true; + + if (dialog.ShowDialog() == DialogResult.OK) + { + foreach (string file in dialog.FileNames) + { + fileNames.Add(file); + } + } + } + + return fileNames.ToArray(); + } + } +} diff --git a/Source/Settings/SettingsForm.Designer.cs b/Source/Forms/SettingsForm.Designer.cs similarity index 97% rename from Source/Settings/SettingsForm.Designer.cs rename to Source/Forms/SettingsForm.Designer.cs index ea14638..669406e 100644 --- a/Source/Settings/SettingsForm.Designer.cs +++ b/Source/Forms/SettingsForm.Designer.cs @@ -1,4 +1,4 @@ -namespace RehauSku.Settings +namespace RehauSku.Forms { partial class SettingsForm { diff --git a/Source/Settings/SettingsForm.cs b/Source/Forms/SettingsForm.cs similarity index 76% rename from Source/Settings/SettingsForm.cs rename to Source/Forms/SettingsForm.cs index 59edf22..4dffadb 100644 --- a/Source/Settings/SettingsForm.cs +++ b/Source/Forms/SettingsForm.cs @@ -8,7 +8,7 @@ using System.Text; using System.Threading.Tasks; using System.Windows.Forms; -namespace RehauSku.Settings +namespace RehauSku.Forms { public partial class SettingsForm : Form { @@ -17,9 +17,5 @@ namespace RehauSku.Settings InitializeComponent(); } - private void button1_Click(object sender, EventArgs e) - { - - } } } diff --git a/Source/Settings/SettingsForm.resx b/Source/Forms/SettingsForm.resx similarity index 100% rename from Source/Settings/SettingsForm.resx rename to Source/Forms/SettingsForm.resx diff --git a/Source/PriceListTools/ExportTool.cs b/Source/PriceListTools/ExportTool.cs new file mode 100644 index 0000000..02def5b --- /dev/null +++ b/Source/PriceListTools/ExportTool.cs @@ -0,0 +1,97 @@ +using ExcelDna.Integration; +using Microsoft.Office.Interop.Excel; +using RehauSku.Assistant; +using System; +using System.Collections.Generic; + +namespace RehauSku.PriceListTools +{ + class ExportTool : IDisposable + { + private Application ExcelApp; + private Dictionary SkuAmount { get; set; } + private Range Selection { get; set; } + + public ExportTool() + { + this.ExcelApp = (Application)ExcelDnaUtil.Application; + Selection = ExcelApp.Selection; + + if (IsRangeValid()) + _FillSkuAmountDict(); + } + + public bool IsRangeValid() + { + return Selection != null && + Selection.Columns.Count == 2; + } + + private void _FillSkuAmountDict() + { + object[,] cells = Selection.Value2; + SkuAmount = new Dictionary(); + int rowsCount = Selection.Rows.Count; + + for (int row = 1; row <= rowsCount; row++) + { + if (cells[row, 1] == null || cells[row, 2] == null) + continue; + + string sku = null; + double? amount = null; + + for (int column = 1; column <= 2; column++) + { + object current = cells[row, column]; + + if (current.ToString().IsRehauSku()) + { + sku = current.ToString(); + } + + else if (current.GetType() == typeof(string) + && double.TryParse(current.ToString(), out _)) + { + amount = double.Parse((string)current); + } + + else if (current.GetType() == typeof(double)) + { + amount = (double)current; + } + } + + if (sku == null || amount == null) + continue; + + if (SkuAmount.ContainsKey(sku)) + SkuAmount[sku] += amount.Value; + else + SkuAmount.Add(sku, amount.Value); + } + } + + public void ExportToNewFile() + { + string exportFile = PriceListUtil.CreateNewExportFile(); + Workbook wb = ExcelApp.Workbooks.Open(exportFile); + PriceList priceList = new PriceList(wb); + + if (priceList.IsValid()) + priceList.Fill(SkuAmount); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + + } + } +} + diff --git a/Source/PriceListTools/MergeTool.cs b/Source/PriceListTools/MergeTool.cs new file mode 100644 index 0000000..21da41d --- /dev/null +++ b/Source/PriceListTools/MergeTool.cs @@ -0,0 +1,55 @@ +using ExcelDna.Integration; +using Microsoft.Office.Interop.Excel; +using System; +using System.Collections.Generic; + +namespace RehauSku.PriceListTools +{ + class MergeTool : IDisposable + { + private Application ExcelApp; + private Dictionary SkuAmount { get; set; } + + public MergeTool() + { + this.ExcelApp = (Application)ExcelDnaUtil.Application; + this.SkuAmount = new Dictionary(); + } + + public void AddSkuAmountToDict(string[] files) + { + ExcelApp.ScreenUpdating = false; + foreach (string file in files) + { + Workbook wb = ExcelApp.Workbooks.Open(file); + PriceList priceList = new PriceList(wb); + + if (priceList.IsValid()) + SkuAmount.AddValues(priceList); + + wb.Close(); + } + ExcelApp.ScreenUpdating = true; + } + + public void ExportToNewFile(string exportFile) + { + Workbook wb = ExcelApp.Workbooks.Open(exportFile); + PriceList priceList = new PriceList(wb); + + if (priceList.IsValid()) + priceList.Fill(SkuAmount); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + + } + } +} diff --git a/Source/PriceListTools/PriceList.cs b/Source/PriceListTools/PriceList.cs new file mode 100644 index 0000000..1460c07 --- /dev/null +++ b/Source/PriceListTools/PriceList.cs @@ -0,0 +1,87 @@ +using Microsoft.Office.Interop.Excel; +using System.Collections.Generic; + +namespace RehauSku.PriceListTools +{ + class PriceList + { + public readonly Workbook Workbook; + public readonly PriceListSheet OfferSheet; + public readonly PriceListSheet ActiveSheet; + + private const string _amountHeader = "Кол-во"; + private const string _skuHeader = "Актуальный материал"; + private const string _offerSheetHeader = "КП"; + + public PriceList(Workbook workbook) + { + Workbook = workbook; + OfferSheet = new PriceListSheet(workbook.Sheets[_offerSheetHeader]); + + Worksheet active = workbook.ActiveSheet; + + if (active.Name == _offerSheetHeader) + ActiveSheet = OfferSheet; + + else + ActiveSheet = new PriceListSheet(active); + } + + public bool IsValid() + { + return OfferSheet.IsValid() && + ActiveSheet.IsValid(); + } + + public void Fill(Dictionary values) + { + Worksheet ws = OfferSheet.sheet; + ws.Activate(); + + int amountColumn = OfferSheet.amountColumn.Value; + int skuColumn = OfferSheet.skuColumn.Value; + + foreach (KeyValuePair kvp in values) + { + Range cell = ws.Columns[skuColumn].Find(kvp.Key); + ws.Cells[cell.Row, amountColumn].Value = kvp.Value; + } + + AutoFilter filter = ws.AutoFilter; + int firstFilterColumn = filter.Range.Column; + + filter.Range.AutoFilter(amountColumn - firstFilterColumn + 1, "<>"); + ws.Range["A1"].Activate(); + } + + public class PriceListSheet + { + public readonly Worksheet sheet; + public readonly int? headerRow; + public readonly int? amountColumn; + public readonly int? skuColumn; + public object[,] amountCells; + public object[,] skuCells; + + 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; + } + + public bool IsValid() + { + return sheet != null && + headerRow != null && + amountColumn != null && + skuColumn != null; + } + } + } +} + diff --git a/Source/PriceListTools/PriceListUtil.cs b/Source/PriceListTools/PriceListUtil.cs new file mode 100644 index 0000000..14797d9 --- /dev/null +++ b/Source/PriceListTools/PriceListUtil.cs @@ -0,0 +1,41 @@ +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 AddValues(this Dictionary 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); + } + } + } + } +} + diff --git a/Source/Ribbon/RibbonController.cs b/Source/Ribbon/RibbonController.cs index 325b4c6..0090761 100644 --- a/Source/Ribbon/RibbonController.cs +++ b/Source/Ribbon/RibbonController.cs @@ -1,7 +1,8 @@ using System.Runtime.InteropServices; using System.Windows.Forms; using ExcelDna.Integration.CustomUI; -using RehauSku.DataExport; +using RehauSku.PriceListTools; +using RehauSku.Forms; namespace RehauSku.Ribbon { @@ -17,6 +18,7 @@ namespace RehauSku.Ribbon