Файл: Клиентская часть информационной системы для организации розничной электронной торговли одеждой.doc
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 25.10.2023
Просмотров: 58
Скачиваний: 2
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
{
string Description = "Description.doc";
if (File.Exists(Description))
Process.Start(Description);
else
MessageBox.Show("Файл " + Description + " не найден");
}
private void providersToolStripMenuItem_Click(object sender, EventArgs e)
{
FormProvider F = new FormProvider();
F.ShowDialog();
}
private void pointsToolStripMenuItem_Click(object sender, EventArgs e)
{
FormPoint F = new FormPoint();
F.ShowDialog();
}
private void closesToolStripMenuItem_Click(object sender, EventArgs e)
{
FormCloses F = new FormCloses();
F.ShowDialog();
}
private void buyToolStripMenuItem_Click(object sender, EventArgs e)
{
FormBuy F = new FormBuy();
F.ShowDialog();
}
private void reportToolStripMenuItem_Click(object sender, EventArgs e)
{
new FormReport().ShowDialog();
}
}
}
FormCloses.cs
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 Receller
{
public partial class FormCloses : Form
{
public FormCloses()
{
InitializeComponent();
}
public string TableName;
public string Result;
public string ID;
DataSet dataSet = new DataSet();
TextBox[] textBoxes = null;
string Query = "";
new List Visible = null;
List Editable = null;
List Header = null;
private void FormCloses_Load(object sender, EventArgs e)
{
dateTimePicker1_ValueChanged(sender, e);
//Заполнить combobox "точка" именами точек
comboBoxPoint.Items.Clear();
string Query = "Select PointTitle from Points order by PointTitle";
DataSet dataSet = new DataSet();
SQLServer.Open(Query, null, dataSet);
comboBoxPoint.Items.Add("Все");
foreach (DataRow row in dataSet.Tables[0].Rows)
comboBoxPoint.Items.Add(row[0].ToString());
Visible = new List() { false, false, true, true, true, true, true};
Editable = new List() { false, true, true, false, true, true, true };
Header = new List() { "IDClose","IDPoint", "Модель", "Магазин", "Куплено (цена)", "Продано (цена)", "Продано" };
textBoxes = new TextBox[] { null, textBox1, textBox2, textBox3, textBox4, textBox5, textBox6};
TableName = "Closes";
Open();
checkBox1_CheckedChanged(sender, e);
}
void Open()
{
Query = "Select "
+ "Closes.IDClose"
+ ",Closes.IDPoint"
+ ",CloseTitle"
+ ",Points.PointTitle as PointTitle"
+ ",BuyCost"
+ ",SellCost"
+ ",Sold"
+ " from " + TableName
+ " JOIN Points ON Closes.IDPoint = Points.IDPoint";
switch (comboBox1.SelectedIndex)
{
case 1:
Query += " WHERE closes.Sold = 1";
break;
case 2:
Query += " WHERE closes.Sold = 0";
break;
}
if (comboBoxPoint.SelectedIndex>=1)
{
if (Query.IndexOf("WHERE") >= 0)
Query += " AND ";
else Query += " WHERE ";
Query += "PointTitle = " + "'" + comboBoxPoint.SelectedItem.ToString() + "'";
}
Query += " order by CloseTitle";
int? save = null;
if (dataGridView.CurrentCell != null)
save = dataGridView.CurrentCell.RowIndex;
SQLServer.Open(Query, dataGridView, dataSet);
SQLServer.ApplyColumns(dataGridView, Visible, Header);
try
{
if (save != null)
dataGridView.CurrentCell = dataGridView.Rows[(int)save].Cells[2];
}
catch { };
}
private void dataGridView_RowEnter(object sender, DataGridViewCellEventArgs e)
{
SQLServer.SetText(dataGridView, e.RowIndex, textBoxes, Visible);
}
private void buttonAdd_Click(object sender, EventArgs e)
{
SQLServer.Insert(dataGridView, textBoxes, dataSet, TableName, Editable);
Open();
}
private void buttonRemove_Click(object sender, EventArgs e)
{
SQLServer.Delete(dataGridView, textBoxes, dataSet, TableName, Visible);
Open();
}
private void buttonEdit_Click(object sender, EventArgs e)
{
SQLServer.Update(dataGridView, textBoxes, dataSet, TableName, Editable);
Open();
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
textBox6.Text = checkBox1.Checked ? "True" : "False";
buttonSell.Enabled = !checkBox1.Checked;
}
private void textBox6_TextChanged(object sender, EventArgs e)
{
checkBox1.Checked = textBox6.Text == "True";
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
Open();
}
private void textBoxFilter_TextChanged(object sender, EventArgs e)
{
SQLServer.Filter(dataGridView, textBoxFilter.Text);
}
private void comboBoxPoint_SelectedIndexChanged(object sender, EventArgs e)
{
Open();
}
private void buttonMove_Click(object sender, EventArgs e)
{
//Отправить в торговую точку выделенные позиции
//или текущую, если нет выделенных
FormPoint F = new FormPoint();
if (F.ShowDialog() != DialogResult.OK) return;
string ID = F.ID;
List indices = new List();
foreach (DataGridViewCell cell in dataGridView.SelectedCells)
{
DataGridViewRow row = dataGridView.Rows[cell.RowIndex];
indices.Add(Convert.ToInt32(row.Cells[0].Value));
}
if (indices.Count == 0 && dataGridView.CurrentCell != null)
indices.Add(Convert.ToInt32(dataGridView.CurrentRow.Cells[0].Value));
foreach (int index in indices)
{
string Query = "UPDATE Closes SET IDPoint = " + ID + " WHERE IDClose = "+index.ToString();
SQLServer.Exec(Query);
}
Open(); //Обновить
}
private void buttonSelect_Click(object sender, EventArgs e)
{
ID = "";
if (dataGridView.CurrentCell != null)
{
int row = dataGridView.CurrentCell.RowIndex;
ID = dataGridView.Rows[row].Cells[0].Value.ToString();
Result = dataGridView.Rows[row].Cells[2].Value.ToString();
}
}
//Продажа с регистрацией даты
private void buttonSell_Click(object sender, EventArgs e)
{
if (dataGridView.CurrentCell == null) return;
if (checkBox1.Checked) return;
checkBox1.Checked = true;
SQLServer.Update(dataGridView, textBoxes, dataSet, TableName, Editable);
int row = dataGridView.CurrentCell.RowIndex;
string ID = dataGridView.Rows[row].Cells[0].Value.ToString();
string Query = "UPDATE Closes SET SellDate = '"+textBox7.Text+"' WHERE IDClose = " + ID;
SQLServer.Exec(Query);
Open();
}
private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
textBox7.Text = dateTimePicker1.Value.ToString("dd.MM.yyyy");
}
}
}
FormBuy.cs
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 Receller
{
public partial class FormBuy : Form
{
public FormBuy()
{
InitializeComponent();
}
private void button4_Click(object sender, EventArgs e)
{
Close();
}
//Выбрать поставщика
string IDProvider = "";
private void buttonProvider_Click(object sender, EventArgs e)
{
FormProvider F = new FormProvider();
if (F.ShowDialog() != DialogResult.OK) return;
IDProvider = F.ID;
textBox1.Text = F.Result;
}
//Выбрать одежду
string IDClose = "";
private void buttonClose_Click(object sender, EventArgs e)
{
FormCloses F = new FormCloses();
if (F.ShowDialog() != DialogResult.OK) return;
IDClose = F.ID;
textBox2.Text = F.Result;
}
//Выбрать склад
string IDPoint = "";
private void buttonPoint_Click(object sender, EventArgs e)
{
FormPoint F = new FormPoint();
if (F.ShowDialog() != DialogResult.OK) return;
IDPoint = F.ID;
textBox4.Text = F.Result;
}
//Реализовать нужное количество вставок по одному экземпляру одежды
private void buttonDoIt_Click(object sender, EventArgs e)
{
int N;
double Cost;
if (IDProvider==""
|| textBox2.Text==""
|| IDPoint==""
|| !int.TryParse(textBox3.Text,out N)
|| !double.TryParse(textBox5.Text, out Cost)
)
{
MessageBox.Show("Не заполнены необходимые поля", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Stop);
return;
}
/*
int ID = 0;
using (DataSet dataSet = new DataSet())
{
string Query = "Select Max(IDClose) from Closes";
SQLServer.Open(Query, null, dataSet);
ID = Convert.ToInt32(dataSet.Tables[0].Rows[0][0]);
}
*/
for (int i=0; i< N; i++)
{
string Query = "INSERT INTO Closes" + Environment.NewLine
+ "(IDBuy, CloseTitle, BuyCost, SellCost, Sold, IDPoint)" + Environment.NewLine
+ "VALUES (" + Environment.NewLine
+ IDProvider + Environment.NewLine
+ ","+ "'"+ textBox2.Text+"'" + Environment.NewLine
+ ","+ Cost.ToString() + Environment.NewLine
+ "," + (3*Cost).ToString() + Environment.NewLine
+ ",0" + Environment.NewLine
+ "," + IDPoint + Environment.NewLine
+ ")";
SQLServer.Exec(Query);
}
}
}
}
SQLServer.cs (класс для работы с сервером)
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
/*
Класс, обеспечивающий доступ к MS SQL Server
Загрузка и сохранение настроек,
Поиск сервера в окружении,
Подключение/отключение,
Выполнение запроса (Open) - возвращающего результат
Выполнение запроса (Exec) - не возвращающего результат
*/
namespace Receller
{
static class SQLServer
{
public struct Options
{
public bool AutoConnect;
public string ServerName;
}
//Работа с настройками
public static Options LoadOptions(string OptionsFile)
{
Options options = new Options() { AutoConnect = false, ServerName = "" };
if (File.Exists(OptionsFile))
using (StreamReader stream = new StreamReader(OptionsFile))
{
options.AutoConnect = bool.Parse(stream.ReadLine());
options.ServerName = stream.ReadLine();
}
return options;
}
public static void SaveOptions(string OptionsFile, Options options)
{
using (StreamWriter stream = new StreamWriter(OptionsFile))
{
stream.WriteLine(options.AutoConnect);
stream.WriteLine(options.ServerName);
}
}
//Найти все MS серверы в сетевом окружении
//Может потребовать долгое время (или очень долгое время)
public static string[] LocateServers()
{
SqlDataSourceEnumerator instance = SqlDataSourceEnumerator.Instance;
System.Data.DataTable table = instance.GetDataSources();
string[] Result = new string[table.Rows.Count];
int i = 0;
foreach (System.Data.DataRow row in table.Rows)
{
System.Data.DataColumn ServerName = table.Columns[0];
System.Data.DataColumn ServerType = table.Columns[1];
Result[i++] = row[ServerName].ToString() + "\\" + row[ServerType].ToString();
}
return Result;
}
internal static SqlConnection conn = null;
public static bool Connected
{
get { return conn != null; }
}
public static bool Connect(string ServerName, string DBName)
{
string connStr = @"Data Source=" + ServerName +
";Initial Catalog=" + DBName + ";Integrated Security=True";
conn = new SqlConnection(connStr);
try
{
conn.Open();
return true;
}
catch
{
conn.Dispose();
conn = null;
return false;
}
}
public static void Disconnect()
{
if (conn == null) return;
conn.Close();
conn.Dispose();
conn = null;
}
//Выполнить SQL Statement, НЕ возвращающий значения
public static bool Exec(string Query)
{
SqlCommand cmd = new SqlCommand(Query, conn);
if (conn.State == ConnectionState.Closed)
return false;
cmd.ExecuteNonQuery();
cmd.Dispose();
return true;
}
//Выполнить select
//заполнить dataSet
//и заполнить таблицу dataGridView, если она указана
public static bool Open(string Query, DataGridView dataGridView, DataSet dataSet)
{
dataSet.Clear();
if (dataGridView != null) //Настроить столбцы
{
dataGridView.AutoGenerateColumns = true;
dataGridView.DataSource = dataSet;
}
try //Выполнить запрос
{
SqlDataAdapter sd = new SqlDataAdapter(Query, conn);
SqlCommand cm = new SqlCommand(Query, conn);
sd.SelectCommand = cm;
sd.Fill(dataSet, "Table1"); //Имя таблицы произвольное
if (dataGridView != null)
{
dataGridView.DataMember = "Table1"; //Главное, чтобы совпадало
dataGridView.Refresh();
}
return true;
}
catch
{
return false;
}
}
//Выполнить агрегатор, возвращающий ровно одно значение
//такой как Count, AVG, SUM итп
public static double ExecAggregator(string Query)
{
using (DataSet dataSet = new DataSet())
{
try //Выполнить запрос
{
SqlDataAdapter sd = new SqlDataAdapter(Query, conn);
SqlCommand cm = new SqlCommand(Query, conn);
sd.SelectCommand = cm;
sd.Fill(dataSet, "Table1"); //Имя таблицы произвольное
double result = double.Parse(dataSet.Tables[0].Rows[0][0].ToString());
return result;
}
catch
{
return 0;
}
}
}
//Применить описание столбцов
public static void ApplyColumns(DataGridView dgv, List Visible, List Header)
{
foreach (DataGridViewColumn column in dgv.Columns)
column.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
//Скрыть столбцы
for (int k=0; k
dgv.Columns[k].Visible = Visible[k];
//Переименовать столбцы
for (int k = 0; k < Header.Count; k++)
dgv.Columns[k].HeaderText = Header[k];
}
//Установить значение в текстовых полях
public static void SetText(DataGridView dataGridView, int row, TextBox[] textBoxes, List use)
{
int start = 0;
foreach (TextBox textBox in textBoxes)
{
if (textBoxes[start] != null)
if (dataGridView.Rows[row].Cells[start].Value != null)
textBox.Text = dataGridView.Rows[row].Cells[start].Value.ToString();
start++;
}
}
//Получить список столбцов
static List Columns(DataTable dataTable, List use)
{
List result = new List();
int start = 0;
int stop = dataTable.Columns.Count - 1;
for (int k = start; k <= stop; k++)
if (use[k])
result.Add(dataTable.Columns[k].ColumnName);
return result;
}
//Получить список значений
static List Values(DataTable dataTable, TextBox[] textBox, List use)
{
int start = 0;
List result = new List();
foreach (TextBox text in textBox)
{
if (!use[start]) { start++; continue; }
if (text == null) { start++; continue; }
//Нужны ли кавычки?
bool Need = dataTable.Columns[start].DataType == Type.GetType("System.DateTime");
Need |= dataTable.Columns[start].DataType == Type.GetType("System.String");
if (Need)
result.Add("'" + text.Text + "'");
else
{
double value = 0;
if (!double.TryParse(text.Text, out value))
{
bool b = false;
if (bool.TryParse(text.Text,out b))
value = b?1:0;
}
result.Add(value.ToString());
}
start++;
}
return result;
}
//Преобразовать список строк в одну строку
public static string ListToString(List list)
{
string result = "";
if (list.Count == 0) return result;
result += list[0];
for (int k = 1; k < list.Count; k++)
result += "," + list[k];
return result;
}
//Типичный Insert
public static void Insert(DataGridView dataGridView, TextBox[] textBoxes, DataSet dataSet, string TableName, List use)
{
//Определить полезные строки
DataTable table = dataSet.Tables[0];
//Составить список столбцов
List columns = Columns(table, use);
//Составить список значений
List values = Values(table, textBoxes, use);
//Подготовить запрос
string Q = "Insert into " + TableName + " ( ";
//Список имен столбцов
Q += ListToString(columns);
Q += " ) VALUES (";
//Список значений
Q += ListToString(values);
Q += ")";
//Выполнить запрос
Exec(Q);
}
//Типичный Update
public static void Update(DataGridView dataGridView, TextBox[] textBoxes, DataSet dataSet, string TableName, List use)
{
if (dataGridView.CurrentCell == null) return;
int row = dataGridView.CurrentCell.RowIndex;
//Определить полезные строки
DataTable table = dataSet.Tables[0];
string IDName = table.Columns[0].ColumnName;
string IDValue = dataGridView.Rows[row].Cells[0].Value.ToString();
if (table.Columns[0].DataType == Type.GetType("System.String"))
IDValue = "'" + IDValue + "'";
//Составить список столбцов
List columns = Columns(table, use);
//Составить список значений
List values = Values(table, textBoxes, use);
//Подготовить запрос
string Q = "Update " + TableName + " set ";
//ColumnList ValueList
for (int k = 0; k < columns.Count; k++)
{
if (k != 0) Q += ",";
Q += columns[k] + " = " + values[k];
}
Q += " Where " + IDName + " = " + IDValue;
//Выполнить запрос
Exec(Q);
}
//Типичный Delete
public static void Delete(DataGridView dataGridView, TextBox[] textBoxes, DataSet dataSet, string TableName, List use)
{
if (dataGridView.CurrentCell == null) return;
int row = dataGridView.CurrentCell.RowIndex;
int queryindex;
for (queryindex = 0; queryindex < textBoxes.Length; queryindex++)
if (textBoxes[queryindex] != null && use[queryindex])
break;
//Определить полезные строки
DataTable table = dataSet.Tables[0];
string IDName = table.Columns[0].ColumnName;
string IDValue = dataGridView.Rows[row].Cells[0].Value.ToString();
if (table.Columns[0].DataType == Type.GetType("System.String"))
IDValue = "'" + IDValue + "'";
//Спросить про удаление
if (MessageBox.Show("Удалить " + textBoxes[queryindex].Text, "Подтвердите удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) return;
//Подготовить запрос
string Q = "Delete from " + TableName + " Where " + IDName + " = " + IDValue;
//Выполнить запрос
Exec(Q);
}
//Фильтрация таблицы "на месте", без изменения выборки
//Скрыть все строки, в которых нет указанной подстроки
public static void Filter(DataGridView dgv, string Text)
{
Text = Text.ToLower();
foreach (DataGridViewRow Row in dgv.Rows)
{
bool contains = false;
foreach (DataGridViewCell cell in Row.Cells)
{
if (cell.Value == null) continue;
if (!dgv.Columns[cell.ColumnIndex].Visible) continue;
contains |= (cell.Value.ToString().ToLower().IndexOf(Text) >= 0);
if (contains) break;
}
if (contains)
Row.Height = 20;
else
Row.Height = -1;
}
}
}
}
Код тестирующего юнита UnitTest.cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Receller;
using static Receller.SQLServer;
using System.IO;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Data;
namespace UnitTest
{
[TestClass]
public class UnitTest
{
[TestMethod]
public void TestOptions()
{
//Load/Save Options
string FileName = Path.GetDirectoryName(Application.ExecutablePath) + "\\test.options";
//Создать
Options options = new SQLServer.Options()
{
AutoConnect = false,
ServerName = "Test"
};
//Сохранить
SaveOptions(FileName, options);
//Испортить
options = new SQLServer.Options()
{
AutoConnect = true,
ServerName = "Other"
};
//Загрузить
options = LoadOptions(FileName);
//Проверить
Assert.AreEqual(false, options.AutoConnect);
Assert.AreEqual("Test", options.ServerName);
}
[TestMethod]
public void TestListToString()
{
List list = new List() { "1", "2", "10" };
string s = ListToString(list);
Assert.AreEqual("1,2,10", s);
}
[TestMethod]
public void TestColumns()
{
DataTable DT = new DataTable();
DT.Columns.Add("C1", Type.GetType("System.String"));
DT.Columns.Add("C2", Type.GetType("System.Int32"));
List columns = Columns(DT, new List() { true, true });
string s = ListToString(columns);
Assert.AreEqual("C1,C2", s);
}
[TestMethod]
public void TestValues()
{
TextBox t1 = new TextBox() { Text = "1" };
TextBox t2 = new TextBox() { Text = "2" };
TextBox[] T = new TextBox[] { t1, t2 };
DataTable DT = new DataTable();
DT.Columns.Add("C1", Type.GetType("System.String"));
DT.Columns.Add("C2", Type.GetType("System.Int32"));
List values = Values(DT, T, new List() { true, true });
string s = ListToString(values);
Assert.AreEqual("'1',2", s);
}
}
}
Приложение Б SQL-скрипт для создания БД
-- Создание базы Receller
CREATE DATABASE Receller
ON PRIMARY
( NAME = Receller,
FILENAME = N'Receller',
SIZE = 3 MB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 10 % )
LOG ON
( NAME = Receller,
FILENAME = N'Receller_Log.ldf',
SIZE = 3 MB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 10 % )
GO
ALTER DATABASE Receller
SET RECOVERY SIMPLE
GO
-- Создание таблиц
USE Receller
CREATE TABLE Buy
(
IDBuy integer IDENTITY ( 1,1 ) ,
BuyQuantity integer NOT NULL ,
IDProvider integer NOT NULL ,
IDClose integer NOT NULL ,
BuyDate datetime NOT NULL ,
BuyDescription varchar(200) NULL
)
go
ALTER TABLE Buy
ADD CONSTRAINT XPKBuy PRIMARY KEY CLUSTERED (IDBuy ASC,IDProvider ASC,IDClose ASC)
go
CREATE TABLE Closes
(
IDClose integer IDENTITY ( 1,1 ) ,
IDBuy integer NULL , -- справочное поле
CloseTitle varchar(200) NOT NULL ,
BuyCost real NOT NULL ,
SellCost real NOT NULL ,
Sold bit NOT NULL ,
SellDate datetime NULL,
IDPoint integer NOT NULL
)
go
ALTER TABLE Closes
ADD CONSTRAINT XPKCloses PRIMARY KEY CLUSTERED (IDClose ASC)
go
CREATE TABLE Points
(
IDPoint integer IDENTITY ( 1,1 ) ,
PointTitle varchar(20) NOT NULL ,
PointAddress varchar(200) NOT NULL ,
PointDirector varchar(200) NOT NULL
)
go
ALTER TABLE Points
ADD CONSTRAINT XPKPoints PRIMARY KEY CLUSTERED (IDPoint ASC)
go
CREATE TABLE Provider
(
IDProvider integer IDENTITY ( 1,1 ) ,
ProviderTitle varchar(20) NOT NULL ,
ProviderAttributes varchar(200) NOT NULL
)
go
ALTER TABLE Provider
ADD CONSTRAINT XPKProvider PRIMARY KEY CLUSTERED (IDProvider ASC)
go
CREATE TABLE Sell
(
IDSell integer IDENTITY ( 1,1 ) ,
IDPoint integer NOT NULL ,
IDClose integer NOT NULL ,
SellDate datetime NOT NULL
)
go
ALTER TABLE Sell
ADD CONSTRAINT XPKSell PRIMARY KEY CLUSTERED (IDSell ASC,IDPoint ASC,IDClose ASC)
go
Внешний вид графического материала
Внешний вид графического материала, выполненного на отдельных листах представлен на рисунках В.1 – В.5.
Перечень графического материала:
лист 1: Диаграмма IDEF0 (рисунок В.1),
лист 2: Диаграмма вариантов использования (рисунок В.2),
лист 3: Реляционная модель данных (рисунок В.3),
лист 4: Диаграмма развертывания (рисунок В.4),
лист 5: Диаграмма состояний (рисунок В.5).
Постановка задачи
Рисунок Б.1 – Диаграмма IDEF0
Рисунок Б.3 – Реляционная модель данных.
Рисунок Б.4 – Диаграмма развертывания
Рисунок Б.5 – Диаграмма состояний
string Description = "Description.doc";
if (File.Exists(Description))
Process.Start(Description);
else
MessageBox.Show("Файл " + Description + " не найден");
}
private void providersToolStripMenuItem_Click(object sender, EventArgs e)
{
FormProvider F = new FormProvider();
F.ShowDialog();
}
private void pointsToolStripMenuItem_Click(object sender, EventArgs e)
{
FormPoint F = new FormPoint();
F.ShowDialog();
}
private void closesToolStripMenuItem_Click(object sender, EventArgs e)
{
FormCloses F = new FormCloses();
F.ShowDialog();
}
private void buyToolStripMenuItem_Click(object sender, EventArgs e)
{
FormBuy F = new FormBuy();
F.ShowDialog();
}
private void reportToolStripMenuItem_Click(object sender, EventArgs e)
{
new FormReport().ShowDialog();
}
}
}
FormCloses.cs
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 Receller
{
public partial class FormCloses : Form
{
public FormCloses()
{
InitializeComponent();
}
public string TableName;
public string Result;
public string ID;
DataSet dataSet = new DataSet();
TextBox[] textBoxes = null;
string Query = "";
new List
List
List
private void FormCloses_Load(object sender, EventArgs e)
{
dateTimePicker1_ValueChanged(sender, e);
//Заполнить combobox "точка" именами точек
comboBoxPoint.Items.Clear();
string Query = "Select PointTitle from Points order by PointTitle";
DataSet dataSet = new DataSet();
SQLServer.Open(Query, null, dataSet);
comboBoxPoint.Items.Add("Все");
foreach (DataRow row in dataSet.Tables[0].Rows)
comboBoxPoint.Items.Add(row[0].ToString());
Visible = new List
Editable = new List
Header = new List
textBoxes = new TextBox[] { null, textBox1, textBox2, textBox3, textBox4, textBox5, textBox6};
TableName = "Closes";
Open();
checkBox1_CheckedChanged(sender, e);
}
void Open()
{
Query = "Select "
+ "Closes.IDClose"
+ ",Closes.IDPoint"
+ ",CloseTitle"
+ ",Points.PointTitle as PointTitle"
+ ",BuyCost"
+ ",SellCost"
+ ",Sold"
+ " from " + TableName
+ " JOIN Points ON Closes.IDPoint = Points.IDPoint";
switch (comboBox1.SelectedIndex)
{
case 1:
Query += " WHERE closes.Sold = 1";
break;
case 2:
Query += " WHERE closes.Sold = 0";
break;
}
if (comboBoxPoint.SelectedIndex>=1)
{
if (Query.IndexOf("WHERE") >= 0)
Query += " AND ";
else Query += " WHERE ";
Query += "PointTitle = " + "'" + comboBoxPoint.SelectedItem.ToString() + "'";
}
Query += " order by CloseTitle";
int? save = null;
if (dataGridView.CurrentCell != null)
save = dataGridView.CurrentCell.RowIndex;
SQLServer.Open(Query, dataGridView, dataSet);
SQLServer.ApplyColumns(dataGridView, Visible, Header);
try
{
if (save != null)
dataGridView.CurrentCell = dataGridView.Rows[(int)save].Cells[2];
}
catch { };
}
private void dataGridView_RowEnter(object sender, DataGridViewCellEventArgs e)
{
SQLServer.SetText(dataGridView, e.RowIndex, textBoxes, Visible);
}
private void buttonAdd_Click(object sender, EventArgs e)
{
SQLServer.Insert(dataGridView, textBoxes, dataSet, TableName, Editable);
Open();
}
private void buttonRemove_Click(object sender, EventArgs e)
{
SQLServer.Delete(dataGridView, textBoxes, dataSet, TableName, Visible);
Open();
}
private void buttonEdit_Click(object sender, EventArgs e)
{
SQLServer.Update(dataGridView, textBoxes, dataSet, TableName, Editable);
Open();
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
textBox6.Text = checkBox1.Checked ? "True" : "False";
buttonSell.Enabled = !checkBox1.Checked;
}
private void textBox6_TextChanged(object sender, EventArgs e)
{
checkBox1.Checked = textBox6.Text == "True";
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
Open();
}
private void textBoxFilter_TextChanged(object sender, EventArgs e)
{
SQLServer.Filter(dataGridView, textBoxFilter.Text);
}
private void comboBoxPoint_SelectedIndexChanged(object sender, EventArgs e)
{
Open();
}
private void buttonMove_Click(object sender, EventArgs e)
{
//Отправить в торговую точку выделенные позиции
//или текущую, если нет выделенных
FormPoint F = new FormPoint();
if (F.ShowDialog() != DialogResult.OK) return;
string ID = F.ID;
List
foreach (DataGridViewCell cell in dataGridView.SelectedCells)
{
DataGridViewRow row = dataGridView.Rows[cell.RowIndex];
indices.Add(Convert.ToInt32(row.Cells[0].Value));
}
if (indices.Count == 0 && dataGridView.CurrentCell != null)
indices.Add(Convert.ToInt32(dataGridView.CurrentRow.Cells[0].Value));
foreach (int index in indices)
{
string Query = "UPDATE Closes SET IDPoint = " + ID + " WHERE IDClose = "+index.ToString();
SQLServer.Exec(Query);
}
Open(); //Обновить
}
private void buttonSelect_Click(object sender, EventArgs e)
{
ID = "";
if (dataGridView.CurrentCell != null)
{
int row = dataGridView.CurrentCell.RowIndex;
ID = dataGridView.Rows[row].Cells[0].Value.ToString();
Result = dataGridView.Rows[row].Cells[2].Value.ToString();
}
}
//Продажа с регистрацией даты
private void buttonSell_Click(object sender, EventArgs e)
{
if (dataGridView.CurrentCell == null) return;
if (checkBox1.Checked) return;
checkBox1.Checked = true;
SQLServer.Update(dataGridView, textBoxes, dataSet, TableName, Editable);
int row = dataGridView.CurrentCell.RowIndex;
string ID = dataGridView.Rows[row].Cells[0].Value.ToString();
string Query = "UPDATE Closes SET SellDate = '"+textBox7.Text+"' WHERE IDClose = " + ID;
SQLServer.Exec(Query);
Open();
}
private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
{
textBox7.Text = dateTimePicker1.Value.ToString("dd.MM.yyyy");
}
}
}
FormBuy.cs
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 Receller
{
public partial class FormBuy : Form
{
public FormBuy()
{
InitializeComponent();
}
private void button4_Click(object sender, EventArgs e)
{
Close();
}
//Выбрать поставщика
string IDProvider = "";
private void buttonProvider_Click(object sender, EventArgs e)
{
FormProvider F = new FormProvider();
if (F.ShowDialog() != DialogResult.OK) return;
IDProvider = F.ID;
textBox1.Text = F.Result;
}
//Выбрать одежду
string IDClose = "";
private void buttonClose_Click(object sender, EventArgs e)
{
FormCloses F = new FormCloses();
if (F.ShowDialog() != DialogResult.OK) return;
IDClose = F.ID;
textBox2.Text = F.Result;
}
//Выбрать склад
string IDPoint = "";
private void buttonPoint_Click(object sender, EventArgs e)
{
FormPoint F = new FormPoint();
if (F.ShowDialog() != DialogResult.OK) return;
IDPoint = F.ID;
textBox4.Text = F.Result;
}
//Реализовать нужное количество вставок по одному экземпляру одежды
private void buttonDoIt_Click(object sender, EventArgs e)
{
int N;
double Cost;
if (IDProvider==""
|| textBox2.Text==""
|| IDPoint==""
|| !int.TryParse(textBox3.Text,out N)
|| !double.TryParse(textBox5.Text, out Cost)
)
{
MessageBox.Show("Не заполнены необходимые поля", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Stop);
return;
}
/*
int ID = 0;
using (DataSet dataSet = new DataSet())
{
string Query = "Select Max(IDClose) from Closes";
SQLServer.Open(Query, null, dataSet);
ID = Convert.ToInt32(dataSet.Tables[0].Rows[0][0]);
}
*/
for (int i=0; i< N; i++)
{
string Query = "INSERT INTO Closes" + Environment.NewLine
+ "(IDBuy, CloseTitle, BuyCost, SellCost, Sold, IDPoint)" + Environment.NewLine
+ "VALUES (" + Environment.NewLine
+ IDProvider + Environment.NewLine
+ ","+ "'"+ textBox2.Text+"'" + Environment.NewLine
+ ","+ Cost.ToString() + Environment.NewLine
+ "," + (3*Cost).ToString() + Environment.NewLine
+ ",0" + Environment.NewLine
+ "," + IDPoint + Environment.NewLine
+ ")";
SQLServer.Exec(Query);
}
}
}
}
SQLServer.cs (класс для работы с сервером)
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
/*
Класс, обеспечивающий доступ к MS SQL Server
Загрузка и сохранение настроек,
Поиск сервера в окружении,
Подключение/отключение,
Выполнение запроса (Open) - возвращающего результат
Выполнение запроса (Exec) - не возвращающего результат
*/
namespace Receller
{
static class SQLServer
{
public struct Options
{
public bool AutoConnect;
public string ServerName;
}
//Работа с настройками
public static Options LoadOptions(string OptionsFile)
{
Options options = new Options() { AutoConnect = false, ServerName = "" };
if (File.Exists(OptionsFile))
using (StreamReader stream = new StreamReader(OptionsFile))
{
options.AutoConnect = bool.Parse(stream.ReadLine());
options.ServerName = stream.ReadLine();
}
return options;
}
public static void SaveOptions(string OptionsFile, Options options)
{
using (StreamWriter stream = new StreamWriter(OptionsFile))
{
stream.WriteLine(options.AutoConnect);
stream.WriteLine(options.ServerName);
}
}
//Найти все MS серверы в сетевом окружении
//Может потребовать долгое время (или очень долгое время)
public static string[] LocateServers()
{
SqlDataSourceEnumerator instance = SqlDataSourceEnumerator.Instance;
System.Data.DataTable table = instance.GetDataSources();
string[] Result = new string[table.Rows.Count];
int i = 0;
foreach (System.Data.DataRow row in table.Rows)
{
System.Data.DataColumn ServerName = table.Columns[0];
System.Data.DataColumn ServerType = table.Columns[1];
Result[i++] = row[ServerName].ToString() + "\\" + row[ServerType].ToString();
}
return Result;
}
internal static SqlConnection conn = null;
public static bool Connected
{
get { return conn != null; }
}
public static bool Connect(string ServerName, string DBName)
{
string connStr = @"Data Source=" + ServerName +
";Initial Catalog=" + DBName + ";Integrated Security=True";
conn = new SqlConnection(connStr);
try
{
conn.Open();
return true;
}
catch
{
conn.Dispose();
conn = null;
return false;
}
}
public static void Disconnect()
{
if (conn == null) return;
conn.Close();
conn.Dispose();
conn = null;
}
//Выполнить SQL Statement, НЕ возвращающий значения
public static bool Exec(string Query)
{
SqlCommand cmd = new SqlCommand(Query, conn);
if (conn.State == ConnectionState.Closed)
return false;
cmd.ExecuteNonQuery();
cmd.Dispose();
return true;
}
//Выполнить select
//заполнить dataSet
//и заполнить таблицу dataGridView, если она указана
public static bool Open(string Query, DataGridView dataGridView, DataSet dataSet)
{
dataSet.Clear();
if (dataGridView != null) //Настроить столбцы
{
dataGridView.AutoGenerateColumns = true;
dataGridView.DataSource = dataSet;
}
try //Выполнить запрос
{
SqlDataAdapter sd = new SqlDataAdapter(Query, conn);
SqlCommand cm = new SqlCommand(Query, conn);
sd.SelectCommand = cm;
sd.Fill(dataSet, "Table1"); //Имя таблицы произвольное
if (dataGridView != null)
{
dataGridView.DataMember = "Table1"; //Главное, чтобы совпадало
dataGridView.Refresh();
}
return true;
}
catch
{
return false;
}
}
//Выполнить агрегатор, возвращающий ровно одно значение
//такой как Count, AVG, SUM итп
public static double ExecAggregator(string Query)
{
using (DataSet dataSet = new DataSet())
{
try //Выполнить запрос
{
SqlDataAdapter sd = new SqlDataAdapter(Query, conn);
SqlCommand cm = new SqlCommand(Query, conn);
sd.SelectCommand = cm;
sd.Fill(dataSet, "Table1"); //Имя таблицы произвольное
double result = double.Parse(dataSet.Tables[0].Rows[0][0].ToString());
return result;
}
catch
{
return 0;
}
}
}
//Применить описание столбцов
public static void ApplyColumns(DataGridView dgv, List
{
foreach (DataGridViewColumn column in dgv.Columns)
column.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
//Скрыть столбцы
for (int k=0; k
dgv.Columns[k].Visible = Visible[k];
//Переименовать столбцы
for (int k = 0; k < Header.Count; k++)
dgv.Columns[k].HeaderText = Header[k];
}
//Установить значение в текстовых полях
public static void SetText(DataGridView dataGridView, int row, TextBox[] textBoxes, List
{
int start = 0;
foreach (TextBox textBox in textBoxes)
{
if (textBoxes[start] != null)
if (dataGridView.Rows[row].Cells[start].Value != null)
textBox.Text = dataGridView.Rows[row].Cells[start].Value.ToString();
start++;
}
}
//Получить список столбцов
static List
{
List
int start = 0;
int stop = dataTable.Columns.Count - 1;
for (int k = start; k <= stop; k++)
if (use[k])
result.Add(dataTable.Columns[k].ColumnName);
return result;
}
//Получить список значений
static List
{
int start = 0;
List
foreach (TextBox text in textBox)
{
if (!use[start]) { start++; continue; }
if (text == null) { start++; continue; }
//Нужны ли кавычки?
bool Need = dataTable.Columns[start].DataType == Type.GetType("System.DateTime");
Need |= dataTable.Columns[start].DataType == Type.GetType("System.String");
if (Need)
result.Add("'" + text.Text + "'");
else
{
double value = 0;
if (!double.TryParse(text.Text, out value))
{
bool b = false;
if (bool.TryParse(text.Text,out b))
value = b?1:0;
}
result.Add(value.ToString());
}
start++;
}
return result;
}
//Преобразовать список строк в одну строку
public static string ListToString(List
{
string result = "";
if (list.Count == 0) return result;
result += list[0];
for (int k = 1; k < list.Count; k++)
result += "," + list[k];
return result;
}
//Типичный Insert
public static void Insert(DataGridView dataGridView, TextBox[] textBoxes, DataSet dataSet, string TableName, List
{
//Определить полезные строки
DataTable table = dataSet.Tables[0];
//Составить список столбцов
List
//Составить список значений
List
//Подготовить запрос
string Q = "Insert into " + TableName + " ( ";
//Список имен столбцов
Q += ListToString(columns);
Q += " ) VALUES (";
//Список значений
Q += ListToString(values);
Q += ")";
//Выполнить запрос
Exec(Q);
}
//Типичный Update
public static void Update(DataGridView dataGridView, TextBox[] textBoxes, DataSet dataSet, string TableName, List
{
if (dataGridView.CurrentCell == null) return;
int row = dataGridView.CurrentCell.RowIndex;
//Определить полезные строки
DataTable table = dataSet.Tables[0];
string IDName = table.Columns[0].ColumnName;
string IDValue = dataGridView.Rows[row].Cells[0].Value.ToString();
if (table.Columns[0].DataType == Type.GetType("System.String"))
IDValue = "'" + IDValue + "'";
//Составить список столбцов
List
//Составить список значений
List
//Подготовить запрос
string Q = "Update " + TableName + " set ";
//ColumnList ValueList
for (int k = 0; k < columns.Count; k++)
{
if (k != 0) Q += ",";
Q += columns[k] + " = " + values[k];
}
Q += " Where " + IDName + " = " + IDValue;
//Выполнить запрос
Exec(Q);
}
//Типичный Delete
public static void Delete(DataGridView dataGridView, TextBox[] textBoxes, DataSet dataSet, string TableName, List
{
if (dataGridView.CurrentCell == null) return;
int row = dataGridView.CurrentCell.RowIndex;
int queryindex;
for (queryindex = 0; queryindex < textBoxes.Length; queryindex++)
if (textBoxes[queryindex] != null && use[queryindex])
break;
//Определить полезные строки
DataTable table = dataSet.Tables[0];
string IDName = table.Columns[0].ColumnName;
string IDValue = dataGridView.Rows[row].Cells[0].Value.ToString();
if (table.Columns[0].DataType == Type.GetType("System.String"))
IDValue = "'" + IDValue + "'";
//Спросить про удаление
if (MessageBox.Show("Удалить " + textBoxes[queryindex].Text, "Подтвердите удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) return;
//Подготовить запрос
string Q = "Delete from " + TableName + " Where " + IDName + " = " + IDValue;
//Выполнить запрос
Exec(Q);
}
//Фильтрация таблицы "на месте", без изменения выборки
//Скрыть все строки, в которых нет указанной подстроки
public static void Filter(DataGridView dgv, string Text)
{
Text = Text.ToLower();
foreach (DataGridViewRow Row in dgv.Rows)
{
bool contains = false;
foreach (DataGridViewCell cell in Row.Cells)
{
if (cell.Value == null) continue;
if (!dgv.Columns[cell.ColumnIndex].Visible) continue;
contains |= (cell.Value.ToString().ToLower().IndexOf(Text) >= 0);
if (contains) break;
}
if (contains)
Row.Height = 20;
else
Row.Height = -1;
}
}
}
}
Код тестирующего юнита UnitTest.cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Receller;
using static Receller.SQLServer;
using System.IO;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Data;
namespace UnitTest
{
[TestClass]
public class UnitTest
{
[TestMethod]
public void TestOptions()
{
//Load/Save Options
string FileName = Path.GetDirectoryName(Application.ExecutablePath) + "\\test.options";
//Создать
Options options = new SQLServer.Options()
{
AutoConnect = false,
ServerName = "Test"
};
//Сохранить
SaveOptions(FileName, options);
//Испортить
options = new SQLServer.Options()
{
AutoConnect = true,
ServerName = "Other"
};
//Загрузить
options = LoadOptions(FileName);
//Проверить
Assert.AreEqual(false, options.AutoConnect);
Assert.AreEqual("Test", options.ServerName);
}
[TestMethod]
public void TestListToString()
{
List
string s = ListToString(list);
Assert.AreEqual("1,2,10", s);
}
[TestMethod]
public void TestColumns()
{
DataTable DT = new DataTable();
DT.Columns.Add("C1", Type.GetType("System.String"));
DT.Columns.Add("C2", Type.GetType("System.Int32"));
List
string s = ListToString(columns);
Assert.AreEqual("C1,C2", s);
}
[TestMethod]
public void TestValues()
{
TextBox t1 = new TextBox() { Text = "1" };
TextBox t2 = new TextBox() { Text = "2" };
TextBox[] T = new TextBox[] { t1, t2 };
DataTable DT = new DataTable();
DT.Columns.Add("C1", Type.GetType("System.String"));
DT.Columns.Add("C2", Type.GetType("System.Int32"));
List
string s = ListToString(values);
Assert.AreEqual("'1',2", s);
}
}
}
Приложение Б SQL-скрипт для создания БД
-- Создание базы Receller
CREATE DATABASE Receller
ON PRIMARY
( NAME = Receller,
FILENAME = N'Receller',
SIZE = 3 MB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 10 % )
LOG ON
( NAME = Receller,
FILENAME = N'Receller_Log.ldf',
SIZE = 3 MB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 10 % )
GO
ALTER DATABASE Receller
SET RECOVERY SIMPLE
GO
-- Создание таблиц
USE Receller
CREATE TABLE Buy
(
IDBuy integer IDENTITY ( 1,1 ) ,
BuyQuantity integer NOT NULL ,
IDProvider integer NOT NULL ,
IDClose integer NOT NULL ,
BuyDate datetime NOT NULL ,
BuyDescription varchar(200) NULL
)
go
ALTER TABLE Buy
ADD CONSTRAINT XPKBuy PRIMARY KEY CLUSTERED (IDBuy ASC,IDProvider ASC,IDClose ASC)
go
CREATE TABLE Closes
(
IDClose integer IDENTITY ( 1,1 ) ,
IDBuy integer NULL , -- справочное поле
CloseTitle varchar(200) NOT NULL ,
BuyCost real NOT NULL ,
SellCost real NOT NULL ,
Sold bit NOT NULL ,
SellDate datetime NULL,
IDPoint integer NOT NULL
)
go
ALTER TABLE Closes
ADD CONSTRAINT XPKCloses PRIMARY KEY CLUSTERED (IDClose ASC)
go
CREATE TABLE Points
(
IDPoint integer IDENTITY ( 1,1 ) ,
PointTitle varchar(20) NOT NULL ,
PointAddress varchar(200) NOT NULL ,
PointDirector varchar(200) NOT NULL
)
go
ALTER TABLE Points
ADD CONSTRAINT XPKPoints PRIMARY KEY CLUSTERED (IDPoint ASC)
go
CREATE TABLE Provider
(
IDProvider integer IDENTITY ( 1,1 ) ,
ProviderTitle varchar(20) NOT NULL ,
ProviderAttributes varchar(200) NOT NULL
)
go
ALTER TABLE Provider
ADD CONSTRAINT XPKProvider PRIMARY KEY CLUSTERED (IDProvider ASC)
go
CREATE TABLE Sell
(
IDSell integer IDENTITY ( 1,1 ) ,
IDPoint integer NOT NULL ,
IDClose integer NOT NULL ,
SellDate datetime NOT NULL
)
go
ALTER TABLE Sell
ADD CONSTRAINT XPKSell PRIMARY KEY CLUSTERED (IDSell ASC,IDPoint ASC,IDClose ASC)
go
ПРИЛОЖЕНИЕ В
Внешний вид графического материала
Внешний вид графического материала, выполненного на отдельных листах представлен на рисунках В.1 – В.5.
Перечень графического материала:
лист 1: Диаграмма IDEF0 (рисунок В.1),
лист 2: Диаграмма вариантов использования (рисунок В.2),
лист 3: Реляционная модель данных (рисунок В.3),
лист 4: Диаграмма развертывания (рисунок В.4),
лист 5: Диаграмма состояний (рисунок В.5).
Постановка задачи
Рисунок Б.1 – Диаграмма IDEF0
Рисунок Б.3 – Реляционная модель данных.
Рисунок Б.4 – Диаграмма развертывания
Рисунок Б.5 – Диаграмма состояний