Доброго времени суток, и с вами снова Дайвер aka Интро.
Сегодня мы с вами снова рассмотрим программу моего производства, написанную на .NET C#, при поддержке клуба “Костыли и новые велосипеды”, под названием “Статистика флотилии”.
Итак, помолясь, начнем!
Что сейчас программа умеет делать:
- Выводить на экран статистику флотилии как из файла с списком пилотов, так и из созданного в интерфейсе списка.
- Сортировать данные по любому параметру.
- Импортировать данные в файлы .xlsx (Exel), .csv (OpenOffice), .xml (for Web/Exel)
- Создавать диаграмму на основе полученных данных при выводе их в эксель.
- Читать логфайл битвы (combat.log) и создавать на его основе файлы с списками пилотов по каждой битве, которую провел игрок за время сессии.
- Читать логфайл битвы (combat.log), которая идет в данный момент, загружать список пилотов из текущей битвы и выдавать по ним статистику.
Что хотелось бы добавить (при вашей помощи, или в одно лицо…):
- Внутриигровой оверлей, дабы получить подобие “Оленеметра”.
- Реализовать реалтаймовое чтение лога битвы, дабы оперативно отслеживать подключившихся к битве пилотов.
- Добавить локализацию для англоговорящих пользователей и выкинуть на буржуйский форум.
Найденные баги:
- При попытке отсортировать данные в таблице по “Корпорации” выдает ошибку. С чем связано - не знаю. Сортировка по тэгу и всем остальным параметрам работает корректно.
- При включенном масштабировании Win (!= 100%) интерфейс программы плывет. Как исправить - без понятия. Пока-что для корректного отображения выключайте “Масштабирование интерфейса Windows”. Обнаружено: [@Dimkan84](< base_url >/index.php?/profile/1082962-dimkan84/)
Скриншот программы:
Скрытый текст
Репозиторий на ГитХабе: https://github.com/IntroD1ver/-Star-Conflict_Stat-list-viewer_release
Текущий код программы (для тех, кому лениво на гитхаб, осторожно, много текста):
Скрытый текст
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Newtonsoft.Json.Linq;
using Excel = Microsoft.Office.Interop.Excel;
using System.IO;
using System.Net.Http;
using System.Data;
using System.Text.RegularExpressions;
using System.Text;
namespace _Star_Conflict_Stat_list_viewer
{
public partial class MainForm : Form
{
public Excel.Application app;
private Excel.Sheets excelsheets;
private Excel.Worksheet excelworksheet;
private Excel.Range excelcells;
string pilots_list;
public MainForm()
{
InitializeComponent();
load_to_csv_button.Enabled = false;
load_to_exel_button.Enabled = false;
load_to_xml_button.Enabled = false;
clean_flot_realization.Enabled = false;
load_to_datagridview_table.Enabled = false;
find_file.Enabled = false;
}
private void MainForm_Load(object sender, EventArgs e) // Обработка событий при загрузке приложения
{
pilots_list = “flot_list.txt”;
dataGridView1.Columns.Add(“ID”, “uID”);
dataGridView1.Columns.Add(“Name”, “Никнейм”);
dataGridView1.Columns.Add(“Corp”, “Корпорация”);
dataGridView1.Columns.Add(“CorpTag”, “Тэг”);
dataGridView1.Columns.Add(“PlayBattle”, “Сыграно битв”);
dataGridView1.Columns.Add(“Winrate”, “Винрейт”);
dataGridView1.Columns.Add(“Kill”, “Убийств”);
dataGridView1.Columns.Add(“KillPerBattle”, “Убийств за бой”);
dataGridView1.Columns.Add(“KillDeath”, “Убийств " + “/” + " Смертей”);
dataGridView1.Columns.Add(“HelpPerBattle”, “Помощи за бой”);
dataGridView1.Columns.Add(“DmgPerBattle”, “Урона за бой”);
dataGridView1.Columns.Add(“HealPerBattle”, “Лечения за бой”);
dataGridView1.Columns.Add(“Karma”, “Карма пилота”);
dataGridView1.Columns.Add(“FullShipInAngar”, “Мощь флота”);
if (!File.Exists(pilots_list))
{
FileStream file_create = File.Create(pilots_list);
file_create.Close();
}
bool append = true;
StreamReader new_stream = new StreamReader(pilots_list, append); // создаем поток для считывания списка пилотов
while (!new_stream.EndOfStream) // пока не прочитаем весь файл
{
flot_have.Text = flot_have.Text + new_stream.ReadLine() + Environment.NewLine; // добавляем пилотов текстбокс с составом флота
}
new_stream.Close();
if (flot_have.Text != " " && flot_have.Text != “”)
{
load_to_datagridview_table.Enabled = true;
}
}
private void FocusFile(string file) // Открываем проводник и устанавливаем курсор
{ // на файле с списком пилотов,
System.Diagnostics.Process.Start(“explorer.exe”, @"/select, " + file); // что используется в данный момент
}
public void open_file_dialog() // Открываем диалог для выбора файла с списком пилотов
{
var dialog = new OpenFileDialog();
dialog.Filter = “Файлы txt|*.txt”;
if (dialog.ShowDialog() == DialogResult.OK)
{
pilots_list = dialog.FileName;
load_to_datagridview_table.Enabled = true;
}
StreamReader new_stream = new StreamReader(dialog.FileName); // Создаем поток для считывания списка пилотов
flot_have.Text = null; // Очищаем текстбокс с текущим списком пилотов
while (!new_stream.EndOfStream) // Читаем файл до конца
{
flot_have.Text = flot_have.Text + new_stream.ReadLine() + Environment.NewLine; // Заполняем текстбокс с текущим списком пилотов
}
new_stream.Close();
find_file.Enabled = true;
}
public void new_file_dialog() // Создаем новый файл с списком пилотов (или дополняем текущий)
{ // И заполняем его значениями из текстбокса
string path = “flot_list.txt”;
if (pilots_list != “” || pilots_list != null || pilots_list != " ")
{
path = pilots_list;
}
string text = flot_add.Text;
bool append = true;
StreamWriter output = new StreamWriter(path, append); // Создаем поток для записи в файл
if (!File.Exists(path)) File.Create(path); // Если файла не существует, создаем
if (text != null || text != " ") // Заполняем файл значениями из текстбокса
{
output.WriteLine(text);
}
flot_add.Text = null;
output.Close();
pilots_list = path;
if (text != null || text != " ") // Добавляем значения в текстбокс с текущим списком пилотов
{
flot_have.Text = flot_have.Text + text + Environment.NewLine;
}
find_file.Enabled = true;
}
public async void load_data() // Загружаем данные по текущему списку флота
{
StreamReader stream = new StreamReader(pilots_list); // создаем поток для считывания списка пилотов
List<string> pilots = new List<string>(); // создаем список List, в котором будем хранить считанные данные
while (!stream.EndOfStream)
{
// Читаем строку из файла во временную переменную.
string temp = stream.ReadLine();
// Если достигнут конец файла, прерываем считывание.
if (temp == null) break;
if (temp == " ") continue;
// Пишем считанную строку в итоговую переменную.
pilots.Add(temp);
}
stream.Close();
for (int i = 0; i < pilots.Count; i++)
{
if (pilots.ElementAt(i) == " " || pilots.ElementAt(i) == null) i++;
string urn = (“http://gmt.star-conflict.com/pubapi/v1/userinfo.php?nickname=” + pilots.ElementAt(i)); // Формируем запрос
var uri = new Uri(urn);
var client = new HttpClient(); // Add: using System.Net.Http; // Создаем клиента для запроса
var response = await client.GetAsync(uri); // Совершаем запрос
string results = await response.Content.ReadAsStringAsync(); // Получаем в переменную результат запроса
dynamic root = JObject.Parse(results); // Парсим результат запроса как JSon строку
dataGridView1.Rows.Add(); // Добавляем строку
if (root.code == 0) // Если никнейм существует - составляем строку из элементов root.*
{
double game_played_d = root.data.pvp.gamePlayed;
double gameWin_d = 0;
double winrate_d = 0;
if (root.data.pvp.gameWin >= 2)
{
gameWin_d = root.data.pvp.gameWin;
winrate_d = Math.Round((gameWin_d / (game_played_d - gameWin_d)), 2);
}
double kill_d = root.data.pvp.totalKill;
double m_kill_d = Math.Round(Math.Round((kill_d / game_played_d), 3), 2);
double totalDeath_d = root.data.pvp.totalDeath;
double kill_death_d = Math.Round(Math.Round((kill_d / totalDeath_d), 3), 2);
double totalAssists_d = root.data.pvp.totalAssists;
double m_assists_d = Math.Round(Math.Round((totalAssists_d / game_played_d), 3), 2);
double totalDmgDone_d = root.data.pvp.totalDmgDone;
double m_dmg_d = Math.Round(Math.Round((totalDmgDone_d / game_played_d), 3), 2);
double totalHealDone_d = root.data.pvp.totalHealingDone;
double m_heal_d = Math.Round(Math.Round((totalHealDone_d / game_played_d), 3), 2);
double pr_bonus_d = 0;
if (root.data.prestigeBonus != null) { pr_bonus_d = root.data.prestigeBonus; } // Костыль для заброшенных старых аккаунтов
double fleet_power_d = (pr_bonus_d * 100);
dataGridView1.Rows_.HeaderCell.Value = pilots.ElementAt(i);_
dataGridView1.Rows_.Cells[1].Value = pilots.ElementAt(i);_
dataGridView1.Rows_.Cells[0].Value = root.data.uid;_
dataGridView1.Rows_.Cells[2].Value = “Без корпорации”;_
dataGridView1.Rows_.Cells[3].Value = " “;_
if (root.data.clan != null && root.data.clan.name != null && root.data.clan.tag != null)
{
dataGridView1.Rows_.Cells[2].Value = root.data.clan.name;_
dataGridView1.Rows_.Cells[3].Value = (”[" + root.data.clan.tag + “]”);_
}
else
{
dataGridView1.Rows_.Cells[2].Value = “Без корпорации”;_
dataGridView1.Rows_.Cells[3].Value = " ";_
}
dataGridView1.Rows_.Cells[4].Value = root.data.pvp.gamePlayed;_
dataGridView1.Rows_.Cells[5].Value = winrate_d;_
dataGridView1.Rows_.Cells[6].Value = root.data.pvp.totalKill;_
dataGridView1.Rows_.Cells[7].Value = m_kill_d;_
dataGridView1.Rows_.Cells[8].Value = kill_death_d;_
dataGridView1.Rows_.Cells[9].Value = m_assists_d;_
dataGridView1.Rows_.Cells[10].Value = m_dmg_d;_
dataGridView1.Rows_.Cells[11].Value = m_heal_d;_
dataGridView1.Rows_.Cells[12].Value = root.data.karma;_
dataGridView1.Rows_.Cells[13].Value = fleet_power_d;_
}
else if (root.code == 1 || pilots.ElementAt(i) == null || pilots.ElementAt(i) == " ") // Если никнейм не существует
{
dataGridView1.Rows_.HeaderCell.Value = “[Error]”;_
dataGridView1.Rows_.Cells[0].Value = "[Not found] " + pilots.ElementAt(i);_
for (int j = 1; j <= 13; j++)
{
dataGridView1.Rows_.Cells[j].Value = 0;_
}
}
if (dataGridView1.Rows_.Cells[10] == null)_
{
dataGridView1.Rows.RemoveAt(i);
}
}
dataGridView1.AutoResizeColumns(); // Выравнивание колонок по содержимому
dataGridView1.AutoResizeRowHeadersWidth(0, DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders); // Выравнивание заголовков строк по содержимому
DataGridViewColumn Name = dataGridView1.SortedColumn;
load_to_csv_button.Enabled = true;
load_to_exel_button.Enabled = true;
load_to_xml_button.Enabled = true;
find_file.Enabled = true;
}
public void clean_flot() // Очищаем список флота
{
flot_have.Text = null; // Очищаем текущий список пилотов
File.Delete(pilots_list); // Удаляем текущий файл с списком
clear_data();
load_to_csv_button.Enabled = false;
load_to_exel_button.Enabled = false;
load_to_xml_button.Enabled = false;
find_file.Enabled = false; // Запускаем функцию очистки таблицы dgv
}
private void FinishExcel(Excel.Application XL) // Завершаем процесс эксель
{
if (XL != null)
{
XL.ScreenUpdating = true;
if (!XL.Interactive) XL.Interactive = true;
XL.UserControl = true;
if (XL.Workbooks.Count == 0)
{
XL.Quit();
}
else
{
if (!XL.Visible) XL.Visible = true;
XL.ActiveWorkbook.Saved = true;
}
// System.Runtime.InteropServices.Marshal.ReleaseComObject(XL);
XL = null;
GC.GetTotalMemory(true); // вызов сборщика мусора
// Пока не закрыть приложение EXCEL.EXE будет висеть в процессах
}
}
public void export_to_exel() // Экспорт данных в Эксель
{
app = new Excel.Application();
app.Visible = false;
//app.SheetsInNewWorkbook = 1;//обязательно до создания новой книги
//var workbook = app.Workbooks.Add(1);
string path = Environment.CurrentDirectory + “\flot_list.xlsx”;
string sheet_name_d = DateTime.Now.ToString();
var temp_time = new Regex(":");
Excel.Workbook workbook;
Excel.Worksheet worksheets;
sheet_name_d = temp_time.Replace(sheet_name_d, “.”);
if(File.Exists(path) == false)
{
workbook = app.Workbooks.Add(Environment.CurrentDirectory + “\flot_list_template”);
workbook.SaveAs(Environment.CurrentDirectory + “\flot_list.xlsx”);
}
workbook = app.Workbooks.Open(path);
worksheets = app.Worksheets.Add();
worksheets.Name = sheet_name_d;
app.Columns.ColumnWidth = 17;
app.Cells[1, 2] = “Никнейм”; // Стартовые значения заголовков таблицы
app.Cells[1, 1] = “uID”;
app.Cells[1, 3] = “Корпорация”;
app.Cells[1, 4] = “Тэг”;
app.Cells[1, 5] = “Сыграно битв [x1000]”;
app.Cells[1, 6] = “Винрейт”;
app.Cells[1, 7] = “Убийств [x100000]”;
app.Cells[1, 8] = “Убийств за бой”;
app.Cells[1, 9] = “Убийств” + " / " + “Сметрей”;
app.Cells[1, 10] = “Помощи за бой”;
app.Cells[1, 11] = “Урона за бой [x100000]”;
app.Cells[1, 12] = “Лечения за бой [x100000]”;
app.Cells[1, 13] = “Карма пилота [x100000]”;
app.Cells[1, 14] = “Мощь флота [x10]”;
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
for (int j = 0; j < dataGridView1.ColumnCount; j++)
{
app.Cells_[i + 2, j + 1]_ = dataGridView1.Rows_.Cells[j].Value;_
app.Cells_[i + 2, 5]_ = double.Parse (dataGridView1.Rows_.Cells[4].Value.ToString()) / 1000;_
app.Cells_[i + 2, 7]_ = double.Parse (dataGridView1.Rows_.Cells[6].Value.ToString()) / 100000;_
app.Cells_[i + 2, 11]_ = double.Parse (dataGridView1.Rows_.Cells[10].Value.ToString()) / 100000;_
app.Cells_[i + 2, 12]_ = double.Parse (dataGridView1.Rows_.Cells[11].Value.ToString()) / 100000;_
app.Cells_[i + 2, 13]_ = double.Parse (dataGridView1.Rows_.Cells[12].Value.ToString()) / 100000;_
app.Cells_[i + 2, 14]_ = double.Parse (dataGridView1.Rows_.Cells[13].Value.ToString()) / 10;_
}
}
int z = dataGridView1.Rows.Count + 1;
//Если бы мы открыли несколько книг, то получили ссылку так
//excelappworkbook=excelappworkbooks[1];
//Получаем массив ссылок на листы выбранной книги
excelsheets = workbook.Worksheets;
//Получаем ссылку на лист 1
excelworksheet = (Excel.Worksheet)excelsheets.get_Item(1);
//Выделяем ячейки с данными в таблице
excelcells = excelworksheet.get_Range(“b1”, “n” + z);
//И выбираем их
excelcells.Select();
//Создаем объект Excel.Chart диаграмму по умолчанию
Excel.Chart excelchart = (Excel.Chart)app.Charts.Add();
//Выбираем диграмму - отображаем лист с диаграммой
excelchart.Activate();
excelchart.Select(Type.Missing);
//Изменяем тип диаграммы
app.ActiveChart.ChartType = Excel.XlChartType.xlLine;
//Создаем надпись - Заглавие диаграммы
app.ActiveChart.HasTitle = true;
app.ActiveChart.ChartTitle.Text = “Cтатистика космофлота”;
app.Visible = true;
app.UserControl = true;
FinishExcel(app);
}
public void export_to_xml() // Экспорт данных в .xml файл
{
DataSet ds = new DataSet(); // создаем пока что пустой кэш данных
System.Data.DataTable dt = new System.Data.DataTable(); // создаем пока что пустую таблицу данных
dt.TableName = “pilot”; // название таблицы
// название колонок
dt.Columns.Add(“Никнейм”);
dt.Columns.Add(“uID”);
dt.Columns.Add(“Корпорация”);
dt.Columns.Add(“Тэг”);
dt.Columns.Add(“Сыграно битв”);
dt.Columns.Add(“Винрейт”);
dt.Columns.Add(“Убийств”);
dt.Columns.Add(“Убийств за бой”);
dt.Columns.Add(“Убийств Смертей”);
dt.Columns.Add(“Помощи за бой”);
dt.Columns.Add(“Урона за бой”);
dt.Columns.Add(“Лечения за бой”);
dt.Columns.Add(“Карма пилота”);
dt.Columns.Add(“Мощь флота”);
ds.Tables.Add(dt); //в ds создается таблица, с названием и колонками, созданными выше
foreach (DataGridViewRow r in dataGridView1.Rows) // пока в dataGridView1 есть строки
{
DataRow row = ds.Tables[“pilot”].NewRow(); // создаем новую строку в таблице, занесенной в ds
row[“Никнейм”] = r.Cells[1].Value; //в столбец этой строки заносим данные из первого столбца dataGridView1
row[“uID”] = r.Cells[0].Value;
row[“Корпорация”] = r.Cells[2].Value;
row[“Тэг”] = r.Cells[3].Value;
row[“Сыграно битв”] = r.Cells[4].Value;
row[“Винрейт”] = r.Cells[5].Value;
row[“Убийств”] = r.Cells[6].Value;
row[“Убийств за бой”] = r.Cells[7].Value;
row[“Убийств Смертей”] = r.Cells[8].Value;
row[“Помощи за бой”] = r.Cells[9].Value;
row[“Урона за бой”] = r.Cells[10].Value;
row[“Лечения за бой”] = r.Cells[11].Value;
row[“Карма пилота”] = r.Cells[12].Value;
row[“Мощь флота”] = r.Cells[13].Value;
ds.Tables[“pilot”].Rows.Add(row); //добавление всей этой строки в таблицу ds.
}
ds.WriteXml(“fleet_data.xml”);
}
public void export_to_csv() // Экспорт данных в .csv файл
{
string fileCSV = “”;
saveFileDialog1.Filter = “Файлы csv|*.csv”;
saveFileDialog1.ShowDialog();
for (int f = 0; f < dataGridView1.ColumnCount; f++)
{
fileCSV += (dataGridView1.Columns[f].HeaderText + “;”);
}
fileCSV += “\t\n”; //тут была загвоздка
for (int i = 0; i < dataGridView1.RowCount ; i++)
{
for (int j = 0; j < dataGridView1.ColumnCount; j++)
{
fileCSV += (dataGridView1[j, i].Value).ToString() + “;”;
}
fileCSV += “\t\n”;
}
StreamWriter wr = new StreamWriter(saveFileDialog1.FileName, false, System.Text.Encoding.GetEncoding(“windows-1251”));
wr.Write(fileCSV);
wr.Close();
}
public void clear_data() // Функция очистки таблицы с данными
{
dataGridView1.Rows.Clear();
load_to_csv_button.Enabled = false;
load_to_exel_button.Enabled = false;
load_to_xml_button.Enabled = false;
}
public void read_log_for_gamelist() // Функция считывания логфайла для получения списка игр, и списка пилотов в играх
{
this.comboBox1.ResetText(); // Очищаем комбобокс
this.comboBox1.Items.Clear();
List <string> game = new List<string>(); // создаем список, в котором будем хранить каждую карту
OpenFileDialog open = new OpenFileDialog();
open.Filter = “combat.log | combat.log”; // открываем файл
string dir = Application.StartupPath + “\player_for_game”; // папка, в которой будем хранить список пилотов по каждой игре
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
string startgame = “Start gameplay”; // так же элемент для проверки
string player_example = “Spawn SpaceShip for player”; // элемент для проверки
if (open.ShowDialog() == DialogResult.OK)
{
FileStream fs1 = new FileStream(open.FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); // открываем поток чтения файла с правами для чтения, записи и удаления
StreamReader read = new StreamReader(fs1, Encoding.UTF8); // читаем файл с помощью стримридера, открывается как байткод, переводим прочитанное в UTF8
while (true)
{
string strings = read.ReadLine(); // читаем строку из файла
if (strings == null) // если конец файла - выходим из цикла
{
break;
}
else
if (strings.Contains(startgame)) // если содержит Start gameplay
{
game.Add(strings); // добавляем в лист с списком игр
}
else
continue;
}
read.Close(); // закрываем потоки чтения
fs1.Close();
FileStream fs2 = new FileStream(open.FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); // открываем новый поток чтения файла с правами для чтения, записи и удаления
using (StreamReader reader = new StreamReader(fs2, Encoding.UTF8))
for (int i = 0; i < game.Count; i++)
{
List<string> players = new List<string>();
while (true)
{
string player = reader.ReadLine();
if (player == null) // если конец файла - выходим из цикла
{
break;
}
if (player.Contains(“Start PVE mission”)) // если ПВЕ - выходим из цикла
{
break;
}
if (player.Contains(game.ElementAt(i))) // если содержит номер текущей игры - начинаем считывать список пилотов
{
continue;
}
if (player.Contains(game.ElementAt(game.Count - 1))) // если содержит номер следующей игры - выходим из цикла
{
break;
}
if (i < game.Count - 1)
{
if (player.Contains(game.ElementAt(i + 1)))
{
break;
}
}
if (player.Contains(player_example)) // если в строке есть запись о спавне игрока - заносим в список игроков
{
string q = player.Substring(player.IndexOf(’(’) + 1); // обрезаем строку так, чтоб получилось лишь имя игрока
q = q.Remove(q.IndexOf(’,’));
if (players.Contains(q))
{
continue;
}
else players.Add(q);
}
}
string g = game.ElementAt(i).Substring(46); // обрезаем строку с наименованием карты до читаемого вида
string times = game.ElementAt(i); //
times = times.Remove(times.IndexOf(’ ‘), times.Length - times.IndexOf(’ '));//
times = times.Replace(’:’, ‘.’); //
var gg = g.Remove(g.IndexOf(’,’), g.Length - g.IndexOf(’,’)); //
string path = dir + “\” + times + " [" + gg + “].txt”;
bool append = false; // Если нужно перезаписывать файл
StreamWriter outputs = new StreamWriter(path, append); // Создаем поток для записи в файл
if (!File.Exists(path))
{
File.Create(path); // Если файла не существует, создаем
}
for (int j = 0; j < players.Count; j++)
{
outputs.WriteLine(players.ElementAt(j));
}
outputs.Close();
this.comboBox1.Items.Add(new SelectData(path, times + " [" + gg + “]”));
}
fs2.Close();
}
}
private void new_pilots_Click(object sender, EventArgs e)
{
clear_data();
new_file_dialog();
load_to_datagridview_table.Enabled = true;
}
private void find_file_Click(object sender, EventArgs e)
{
FocusFile(pilots_list);
}
private void open_file_Click(object sender, EventArgs e)
{
open_file_dialog();
}
private void load_to_datagridview_table_Click(object sender, EventArgs e)
{
clear_data();
load_data();
}
private void clean_data_Click(object sender, EventArgs e)
{
clear_data();
}
private void clean_flot_initialize_Click(object sender, EventArgs e)
{
clean_flot_realization.Enabled = true;
}
private void clean_flot_realization_Click(object sender, EventArgs e)
{
clean_flot();
}
private void load_to_exel_button_Click(object sender, EventArgs e)
{
export_to_exel();
}
private void load_to_xml_button_Click(object sender, EventArgs e)
{
export_to_xml();
DialogResult result = MessageBox.Show(“Таблица экспортирована \nОткрыть расположение таблицы?”, “”, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
System.Diagnostics.Process.Start(“explorer.exe”, @"/select, " + “fleet_data.xml”);
}
}
private void load_to_csv_button_Click(object sender, EventArgs e)
{
export_to_csv();
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
FinishExcel(app);
}
private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
{
FinishExcel(app);
}
private void read_log_button_Click(object sender, EventArgs e)
{
}
private void work_button_Click(object sender, EventArgs e)
{
read_log_for_gamelist();
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
load_to_datagridview_table.Enabled = true;
pilots_list = ((SelectData)this.comboBox1.SelectedItem).Value;
flot_have.Text = null;
StreamReader new_stream_combo = new StreamReader(pilots_list); // создаем поток для считывания списка пилотов
while (!new_stream_combo.EndOfStream) // пока не прочитаем весь файл
{
flot_have.Text = flot_have.Text + new_stream_combo.ReadLine() + Environment.NewLine; // добавляем пилотов текстбокс с составом флота
}
new_stream_combo.Close();
}
}
class SelectData // класс для отображения в комбобоксе удобочитаемого текста
{ // вместо полного пути к файлу с пилотами
public readonly string Value;
public readonly string Text;
public SelectData(string Value, string Text)
{
this.Value = Value;
this.Text = Text;
}
public override string ToString()
{
return this.Text;
}
}
}
Хотелось бы получать отзывы по использованию, деньги на кошелек яндекс.кошелек, предложения, замечания, найденные баги. Буду очень рад!
С вами был Дайвер aka Интро, до новых апдейтов багов встреч!
На этом все, далее - архивные данные.
История программы:
Скрытый текст
с чего начиналось:
Скрытый текст
Программа умеет выводить статистику игрока (включая к/д, средний урон за бой, средний хил за бой, etc).
Для работы требуется .Net framework (если нету - инсталлятор подскажет, где взять).
В планах интеграция с читалками лога боя, чтоб получилось что-то вроде оленеметра.
Буду благодарен за отзывы.
Ссылка на программу:
https://yadi.sk/d/Q99eMq7us3XEH
Расширение функционала:
Скрытый текст
Наконец рак на горе свиснул, и я доработал свою программу Star Conflict SV.
Приложение претерпело много изменений как в интерфейсе, так и в логике работы. На данный момент программа умеет показывать статистику флотилии пилотов из файла, создать список пилотов, очистить и удалить список, экспортировать данные в Exel файл. Сортировка пилотов по любому из параметров - так же есть.
Учитывая возможность экспорта данных в Exel, и работу с списком пилотов из файла, вы можете использовать все возможности офисного приложения (создав документ в экселе, переносить туда данные по всему списку пилотов, строить диаграммы развития вашей флотилиикорпорации, да и просто просматривать динамику личного роста себя и любого интересующего вас пилота).
Большая просьба умеющим писать код (и работающим по этой специальности) указать на косяки и показать, что и как можно улучшить в коде.
Скачаете, попробуете - оставьте отзыв, ваше мнение для меня важно.
Ссылка на программу: https://yadi.sk/d/wkMU-0covZqrj
Новая версия программы здесь: [https://forum.star-conflict.ru/index.php?/topic/52894-статистика-флотилии-финальная-сборка/](< base_url >/index.php?/topic/52894-%D1%81%D1%82%D0%B0%D1%82%D0%B8%D1%81%D1%82%D0%B8%D0%BA%D0%B0-%D1%84%D0%BB%D0%BE%D1%82%D0%B8%D0%BB%D0%B8%D0%B8-%D1%84%D0%B8%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F-%D1%81%D0%B1%D0%BE%D1%80%D0%BA%D0%B0/)
Скрины под катом.
Скрытый текст
Исходный код под катом.
Скрытый текст
using System;using System.Collections.Generic;using System.Linq;using System.Windows.Forms;using System.Net.Http;using System.IO;using Newtonsoft.Json.Linq;using Microsoft.Office.Interop.Excel;namespace SC\_List\_Stat\_Viewer{ public partial class Form1 : Form { string pilots\_list; public Form1() { InitializeComponent(); dataGridView1.Columns.Add("Name", "Никнейм"); dataGridView1.Columns.Add("ID", "uID"); dataGridView1.Columns.Add("Corp", "Корпорация"); dataGridView1.Columns.Add("CorpTag", "Тэг"); dataGridView1.Columns.Add("PlayBattle", "Сыграно битв"); dataGridView1.Columns.Add("Winrate", "Винрейт"); dataGridView1.Columns.Add("Kill", "Убийств"); dataGridView1.Columns.Add("KillPerBattle", "Убийств за бой"); dataGridView1.Columns.Add("KillDeath", "Убийств" + "/" + "Смертей"); dataGridView1.Columns.Add("HelpPerBattle", "Помощи за бой"); dataGridView1.Columns.Add("DmgPerBattle", "Урона за бой"); dataGridView1.Columns.Add("HealPerBattle", "Лечения за бой"); dataGridView1.Columns.Add("Karma", "Карма пилота"); dataGridView1.Columns.Add("FullShipInAngar", "Мощь флота"); pilots\_list = "flot\_list.txt"; if (!File.Exists(pilots\_list)) { FileStream file\_create = File.Create(pilots\_list); file\_create.Close(); } } private void FocusFile(string file) { try { System.Diagnostics.Process.Start("explorer.exe", @"/select, " + file); } catch (Exception exc) { } } public void open\_file\_dialog() { var dialog = new OpenFileDialog(); dialog.Filter = "Файлы txt|\*.txt"; if (dialog.ShowDialog() == DialogResult.OK) { pilots\_list = dialog.FileName; button1.Enabled = true; } StreamReader new\_stream = new StreamReader(dialog.FileName); // создаем поток для считывания списка пилотов textBox2.Text = null; while (!new\_stream.EndOfStream) { textBox2.Text = textBox2.Text + new\_stream.ReadLine() + Environment.NewLine; } new\_stream.Close(); } public void new\_file\_dialog() { string path = "flot\_list.txt"; if (pilots\_list != "" || pilots\_list != null || pilots\_list != " ") { path = pilots\_list; } string text = textBox1.Text; bool append = true; StreamWriter output = new StreamWriter(path, append); if (!File.Exists(path)) File.Create(path); if (text != "" || text != " ") { output.WriteLine(text); } textBox1.Text = null; output.Close(); pilots\_list = path; textBox2.Text = textBox2.Text + text + Environment.NewLine; } public void clean\_flot() { textBox2.Text = null; File.Delete(pilots\_list); clear\_data(); } public void export\_to\_exel() { Microsoft.Office.Interop.Excel.Application ExcelApp = new Microsoft.Office.Interop.Excel.Application(); Workbook ExcelWorkBook; Worksheet ExcelWorkSheet; //Книга. ExcelWorkBook = ExcelApp.Workbooks.Add(System.Reflection.Missing.Value); //Таблица. ExcelWorkSheet = (Worksheet)ExcelWorkBook.Worksheets.get\_Item(1); ExcelApp.Cells[1, 1] = "Никнейм"; ExcelApp.Cells[1, 2] = "uID"; ExcelApp.Cells[1, 3] = "Корпорация"; ExcelApp.Cells[1, 4] = "Тэг"; ExcelApp.Cells[1, 5] = "Сыграно битв"; ExcelApp.Cells[1, 6] = "Винрейт"; ExcelApp.Cells[1, 7] = "Убийств"; ExcelApp.Cells[1, 8] = "Убийств за бой"; ExcelApp.Cells[1, 9] = "Убийств" + "/" + "смертей"; ExcelApp.Cells[1, 10] = "Помощи за бой"; ExcelApp.Cells[1, 11] = "Урона за бой"; ExcelApp.Cells[1, 12] = "Лечения за бой"; ExcelApp.Cells[1, 13] = "Карма пилота"; ExcelApp.Cells[1, 14] = "Мощь флота"; for (int i = 0; i \< dataGridView1.Rows.Count; i++) { for (int j = 0; j \< dataGridView1.ColumnCount; j++) { ExcelApp.Cells[i + 2, j + 1] = dataGridView1.Rows.Cells[j].Value; } } //Вызываем нашу созданную эксельку. ExcelApp.Visible = true; ExcelApp.UserControl = true; } public async void load\_data() { button2.Enabled = true; button1.Enabled = false; StreamReader stream = new StreamReader(pilots\_list); // создаем поток для считывания списка пилотов List\<string\> pilots = new List\<string\>(); // создаем список List, в котором будем хранить считанные данные while (!stream.EndOfStream) { // Читаем строку из файла во временную переменную. string temp = stream.ReadLine(); // Если достигнут конец файла, прерываем считывание. if (temp == null) break; // Пишем считанную строку в итоговую переменную. pilots.Add(temp); } stream.Close(); for (int i = 0; i \< pilots.Count; i++) { string urn = ("http://gmt.star-conflict.com/pubapi/v1/userinfo.php?nickname=" + pilots.ElementAt(i)); // Формируем запрос var uri = new Uri(urn); var client = new HttpClient(); // Add: using System.Net.Http; // Создаем клиента для запроса var response = await client.GetAsync(uri); // Совершаем запрос string results = await response.Content.ReadAsStringAsync(); // Получаем в переменную результат запроса dynamic root = JObject.Parse(results); // Парсим результат запроса как JSon строку dataGridView1.Rows.Add(); // Добавляем строку if (root.code == 0) // Если никнейм существует - составляем строку из элементов root.\* { double game\_played\_d = root.data.pvp.gamePlayed; double gameWin\_d = 0; double winrate\_d = 0; if (root.data.pvp.gameWin \>= 2) { gameWin\_d = root.data.pvp.gameWin; winrate\_d = Math.Round((gameWin\_d / (game\_played\_d - gameWin\_d)), 2); } double kill\_d = root.data.pvp.totalKill; double m\_kill\_d = Math.Round(Math.Round((kill\_d / game\_played\_d), 3), 2); double totalDeath\_d = root.data.pvp.totalDeath; double kill\_death\_d = Math.Round(Math.Round((kill\_d / totalDeath\_d), 3), 2); double totalAssists\_d = root.data.pvp.totalAssists; double m\_assists\_d = Math.Round(Math.Round((totalAssists\_d / game\_played\_d), 3), 2); double totalDmgDone\_d = root.data.pvp.totalDmgDone; double m\_dmg\_d = Math.Round(Math.Round((totalDmgDone\_d / game\_played\_d), 3), 2); double totalHealDone\_d = root.data.pvp.totalHealingDone; double m\_heal\_d = Math.Round(Math.Round((totalHealDone\_d / game\_played\_d), 3), 2); double pr\_bonus\_d = 0; if (root.data.prestigeBonus != null) { pr\_bonus\_d = root.data.prestigeBonus; } // Костыль для заброшенных старых аккаунтов double fleet\_power\_d = (pr\_bonus\_d \* 100); dataGridView1.Rows.HeaderCell.Value = pilots.ElementAt(i); dataGridView1.Rows.Cells[0].Value = pilots.ElementAt(i); dataGridView1.Rows.Cells[1].Value = root.data.uid; dataGridView1.Rows.Cells[2].Value = "Без корпорации"; dataGridView1.Rows.Cells[3].Value = null; if (root.data.clan != null && root.data.clan.name != null && root.data.clan.tag != null) { dataGridView1.Rows.Cells[2].Value = root.data.clan.name; dataGridView1.Rows.Cells[3].Value = ("[" + root.data.clan.tag + "]"); } dataGridView1.Rows.Cells[4].Value = root.data.pvp.gamePlayed; dataGridView1.Rows.Cells[5].Value = winrate\_d; dataGridView1.Rows.Cells[6].Value = root.data.pvp.totalKill; dataGridView1.Rows.Cells[7].Value = m\_kill\_d; dataGridView1.Rows.Cells[8].Value = kill\_death\_d; dataGridView1.Rows.Cells[9].Value = m\_assists\_d; dataGridView1.Rows.Cells[10].Value = m\_dmg\_d; dataGridView1.Rows.Cells[11].Value = m\_heal\_d; dataGridView1.Rows.Cells[12].Value = root.data.karma; dataGridView1.Rows.Cells[13].Value = fleet\_power\_d; } else if (root.code == 1 || pilots.ElementAt(i) == null || pilots.ElementAt(i) == " ") // Если никнейм не существует { dataGridView1.Rows.HeaderCell.Value = "[Error]"; dataGridView1.Rows.Cells[0].Value = "[Not found] " + pilots.ElementAt(i); for (int j = 1; j \<= 13; j++) { dataGridView1.Rows.Cells[j].Value = 0; } } if (dataGridView1.Rows.Cells[10] == null) { dataGridView1.Rows.RemoveAt(i); } } dataGridView1.AutoResizeColumns(); // Выравнивание колонок по содержимому dataGridView1.AutoResizeRowHeadersWidth(0, DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders); // Выравнивание заголовков строк по содержимому DataGridViewColumn Name = dataGridView1.SortedColumn; } public void clear\_data() { dataGridView1.Rows.Clear(); } private void button1\_Click(object sender, EventArgs e) { clear\_data(); load\_data(); } private void button2\_Click(object sender, EventArgs e) { clear\_data(); button1.Enabled = true; button2.Enabled = false; } private void button4\_Click(object sender, EventArgs e) { open\_file\_dialog(); } private void button3\_Click(object sender, EventArgs e) { button4.Enabled = false; button1.Enabled = true; button5.Enabled = true; new\_file\_dialog(); } private void button5\_Click(object sender, EventArgs e) { FocusFile(pilots\_list); } private void button6\_Click(object sender, EventArgs e) { button7.Enabled = true; button8.Enabled = true; } private void button7\_Click(object sender, EventArgs e) { button7.Enabled = false; button5.Enabled = false; button1.Enabled = true; button2.Enabled = true; button6.Enabled = true; button8.Enabled = false; button4.Enabled = true; button1.Enabled = false; clean\_flot(); clear\_data(); } private void button8\_Click(object sender, EventArgs e) { button7.Enabled = false; button8.Enabled = false; button6.Enabled = true; } private void Form1\_Load(object sender, EventArgs e) { bool append = true; StreamReader new\_stream = new StreamReader(pilots\_list, append); // создаем поток для считывания списка пилотов while (!new\_stream.EndOfStream) { textBox2.Text = textBox2.Text + new\_stream.ReadLine() + Environment.NewLine; } new\_stream.Close(); button2.Enabled = false; button1.Enabled = false; button7.Enabled = false; button8.Enabled = false; if (textBox2.Text != " " && textBox2.Text != "") button1.Enabled = true; } private void button9\_Click(object sender, EventArgs e) { export\_to\_exel(); } private void label1\_Click(object sender, EventArgs e) { } }}
_ _Вирустоталы под катом.
Скрытый текст
Инсталлятор:
Исполняемый файл (сама программа):
Для Newtonsoft.dll и .config файлов вирустоталы не привожу, по причине отсутствия необходимости.
Скрытый текст
Прикрутил импорт в .xml, .csv, .xlsx
Добавил график по всем пилотам в списке, сравнительный. Слегка изменил вид программы. Файл для импорта в .xlsx уже создан, на каждый импорт данных в эксель создается дополнительный лист (имя листа = время экспорта) и график по всем пилотам в списке.
Провел рефакторинг кода, комменты много где не ставил, ибо устал уже.
По поводу:
В 24.09.2016 в 15:27, Dimkan84 сказал:
Было бы гораздо интересней, если бы в ней можно было бы сравнивать свой и вражеский флот, например вбив в нее ники из своей команды и команды противника, при этом разделить окно на синих и красных.
- Берешь, вбиваешь ники своей команды.
Загружаешь в таблицу. Экспортируешь в эксель. Инициируешь очищение флота. Производишь очистку. Вбиваешь ники противоположной команды. Загружаешь в таблицу. Экспортируешь в эксель. ??? Profit!
Итого, на выходе, у тебя будет две экселевских таблицы в одном файле, на разных листах, и две сравнительных диаграммы. Дальше - свободный полет фантазии и полный доступ к средствам Microsoft Office Excel, верти этими данными как хочешь.
Код под катом, надеюсь стало более читабельно.
Скрытый текст
using System;using System.Collections.Generic;using System.Linq;using System.Windows.Forms;using Newtonsoft.Json.Linq;using Excel = Microsoft.Office.Interop.Excel;using System.IO;using System.Net.Http;using System.Data;using System.Text.RegularExpressions;namespace \_Star\_Conflict\_Stat\_list\_viewer{public partial class MainForm : Form{public Excel.Application app;private Excel.Sheets excelsheets;private Excel.Worksheet excelworksheet;private Excel.Range excelcells; string pilots\_list;public MainForm(){InitializeComponent(); load\_to\_csv\_button.Enabled = false; load\_to\_exel\_button.Enabled = false; load\_to\_xml\_button.Enabled = false; clean\_flot\_realization.Enabled = false; load\_to\_datagridview\_table.Enabled = false; find\_file.Enabled = false;}private void MainForm\_Load(object sender, EventArgs e)// Обработка событий при загрузке приложения{ pilots\_list = "flot\_list.txt"; dataGridView1.Columns.Add("ID", "uID"); dataGridView1.Columns.Add("Name", "Никнейм"); dataGridView1.Columns.Add("Corp", "Корпорация"); dataGridView1.Columns.Add("CorpTag", "Тэг"); dataGridView1.Columns.Add("PlayBattle", "Сыграно битв"); dataGridView1.Columns.Add("Winrate", "Винрейт"); dataGridView1.Columns.Add("Kill", "Убийств"); dataGridView1.Columns.Add("KillPerBattle", "Убийств за бой"); dataGridView1.Columns.Add("KillDeath", "Убийств " + "/" + " Смертей"); dataGridView1.Columns.Add("HelpPerBattle", "Помощи за бой"); dataGridView1.Columns.Add("DmgPerBattle", "Урона за бой"); dataGridView1.Columns.Add("HealPerBattle", "Лечения за бой"); dataGridView1.Columns.Add("Karma", "Карма пилота"); dataGridView1.Columns.Add("FullShipInAngar", "Мощь флота");if (!File.Exists(pilots\_list)){FileStream file\_create = File.Create(pilots\_list); file\_create.Close();}bool append = true;StreamReader new\_stream = new StreamReader(pilots\_list, append);// создаем поток для считывания списка пилотовwhile (!new\_stream.EndOfStream)// пока не прочитаем весь файл{ flot\_have.Text = flot\_have.Text + new\_stream.ReadLine() + Environment.NewLine; // добавляем пилотов текстбокс с составом флота} new\_stream.Close();if (flot\_have.Text != " " && flot\_have.Text != ""){ load\_to\_datagridview\_table.Enabled = true;}}private void FocusFile(string file)// Открываем проводник и устанавливаем курсор {// на файле с списком пилотов,System.Diagnostics.Process.Start("explorer.exe", @"/select, " + file);// что используется в данный момент}public void open\_file\_dialog()// Открываем диалог для выбора файла с списком пилотов{ var dialog = new OpenFileDialog(); dialog.Filter = "Файлы txt|\*.txt";if (dialog.ShowDialog() == DialogResult.OK){ pilots\_list = dialog.FileName; load\_to\_datagridview\_table.Enabled = true;}StreamReader new\_stream = new StreamReader(dialog.FileName);// Создаем поток для считывания списка пилотов flot\_have.Text = null;// Очищаем текстбокс с текущим списком пилотовwhile (!new\_stream.EndOfStream)// Читаем файл до конца{ flot\_have.Text = flot\_have.Text + new\_stream.ReadLine() + Environment.NewLine;// Заполняем текстбокс с текущим списком пилотов} new\_stream.Close(); find\_file.Enabled = true;}public void new\_file\_dialog()// Создаем новый файл с списком пилотов (или дополняем текущий){// И заполняем его значениями из текстбокса string path = "flot\_list.txt";if (pilots\_list != "" || pilots\_list != null || pilots\_list != " "){ path = pilots\_list;} string text = flot\_add.Text;bool append = true;StreamWriter output = new StreamWriter(path, append);// Создаем поток для записи в файлif (!File.Exists(path)) File.Create(path);// Если файла не существует, создаемif (text != null || text != " ")// Заполняем файл значениями из текстбокса { output.WriteLine(text);} flot\_add.Text = null; output.Close(); pilots\_list = path;if (text != null || text != " ")// Добавляем значения в текстбокс с текущим списком пилотов{ flot\_have.Text = flot\_have.Text + text + Environment.NewLine;} find\_file.Enabled = true;}public async void load\_data()// Загружаем данные по текущему списку флота{StreamReader stream = new StreamReader(pilots\_list); // создаем поток для считывания списка пилотовList\<string\> pilots = new List\<string\>();// создаем список List, в котором будем хранить считанные данныеwhile (!stream.EndOfStream){// Читаем строку из файла во временную переменную. string temp = stream.ReadLine();// Если достигнут конец файла, прерываем считывание.if (temp == null) break;if (temp == " ") continue;// Пишем считанную строку в итоговую переменную. pilots.Add(temp);} stream.Close();for (int i = 0; i \< pilots.Count; i++){if (pilots.ElementAt(i) == " " || pilots.ElementAt(i) == null) i++; string urn = ("http://gmt.star-conflict.com/pubapi/v1/userinfo.php?nickname=" + pilots.ElementAt(i)); // Формируем запрос var uri = new Uri(urn); var client = new HttpClient(); // Add: using System.Net.Http; // Создаем клиента для запроса var response = await client.GetAsync(uri);// Совершаем запрос string results = await response.Content.ReadAsStringAsync();// Получаем в переменную результат запроса dynamic root = JObject.Parse(results);// Парсим результат запроса как JSon строку dataGridView1.Rows.Add();// Добавляем строкуif (root.code == 0)// Если никнейм существует - составляем строку из элементов root.\* {double game\_played\_d = root.data.pvp.gamePlayed;double gameWin\_d = 0;double winrate\_d = 0;if (root.data.pvp.gameWin \>= 2){ gameWin\_d = root.data.pvp.gameWin; winrate\_d = Math.Round((gameWin\_d / (game\_played\_d - gameWin\_d)), 2);}double kill\_d = root.data.pvp.totalKill;double m\_kill\_d = Math.Round(Math.Round((kill\_d / game\_played\_d), 3), 2);double totalDeath\_d = root.data.pvp.totalDeath;double kill\_death\_d = Math.Round(Math.Round((kill\_d / totalDeath\_d), 3), 2);double totalAssists\_d = root.data.pvp.totalAssists;double m\_assists\_d = Math.Round(Math.Round((totalAssists\_d / game\_played\_d), 3), 2);double totalDmgDone\_d = root.data.pvp.totalDmgDone;double m\_dmg\_d = Math.Round(Math.Round((totalDmgDone\_d / game\_played\_d), 3), 2);double totalHealDone\_d = root.data.pvp.totalHealingDone;double m\_heal\_d = Math.Round(Math.Round((totalHealDone\_d / game\_played\_d), 3), 2);double pr\_bonus\_d = 0;if (root.data.prestigeBonus != null) { pr\_bonus\_d = root.data.prestigeBonus; }// Костыль для заброшенных старых аккаунтовdouble fleet\_power\_d = (pr\_bonus\_d \* 100); dataGridView1.Rows[i].HeaderCell.Value = pilots.ElementAt(i); dataGridView1.Rows[i].Cells[1].Value = pilots.ElementAt(i); dataGridView1.Rows[i].Cells[0].Value = root.data.uid; dataGridView1.Rows[i].Cells[2].Value = "Без корпорации"; dataGridView1.Rows[i].Cells[3].Value = null;if (root.data.clan != null && root.data.clan.name != null && root.data.clan.tag != null){ dataGridView1.Rows[i].Cells[2].Value = root.data.clan.name; dataGridView1.Rows[i].Cells[3].Value = ("[" + root.data.clan.tag + "]");} dataGridView1.Rows[i].Cells[4].Value = root.data.pvp.gamePlayed; dataGridView1.Rows[i].Cells[5].Value = winrate\_d; dataGridView1.Rows[i].Cells[6].Value = root.data.pvp.totalKill; dataGridView1.Rows[i].Cells[7].Value = m\_kill\_d; dataGridView1.Rows[i].Cells[8].Value = kill\_death\_d; dataGridView1.Rows[i].Cells[9].Value = m\_assists\_d; dataGridView1.Rows[i].Cells[10].Value = m\_dmg\_d; dataGridView1.Rows[i].Cells[11].Value = m\_heal\_d; dataGridView1.Rows[i].Cells[12].Value = root.data.karma; dataGridView1.Rows[i].Cells[13].Value = fleet\_power\_d;}else if (root.code == 1 || pilots.ElementAt(i) == null || pilots.ElementAt(i) == " ")// Если никнейм не существует{ dataGridView1.Rows[i].HeaderCell.Value = "[Error]"; dataGridView1.Rows[i].Cells[0].Value = "[Not found] " + pilots.ElementAt(i);for (int j = 1; j \<= 13; j++){ dataGridView1.Rows[i].Cells[j].Value = 0;}}if (dataGridView1.Rows[i].Cells[10] == null){ dataGridView1.Rows.RemoveAt(i);}} dataGridView1.AutoResizeColumns();// Выравнивание колонок по содержимому dataGridView1.AutoResizeRowHeadersWidth(0, DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders); // Выравнивание заголовков строк по содержимомуDataGridViewColumn Name = dataGridView1.SortedColumn; load\_to\_csv\_button.Enabled = true; load\_to\_exel\_button.Enabled = true; load\_to\_xml\_button.Enabled = true; find\_file.Enabled = true;}public void clean\_flot()// Очищаем список флота{ flot\_have.Text = null;// Очищаем текущий список пилотовFile.Delete(pilots\_list);// Удаляем текущий файл с списком clear\_data(); load\_to\_csv\_button.Enabled = false; load\_to\_exel\_button.Enabled = false; load\_to\_xml\_button.Enabled = false; find\_file.Enabled = false;// Запускаем функцию очистки таблицы dgv}private void FinishExcel(Excel.Application XL)// Завершаем процесс эксель{if (XL != null){ XL.ScreenUpdating = true;if (!XL.Interactive) XL.Interactive = true; XL.UserControl = true;if (XL.Workbooks.Count == 0){ XL.Quit();}else{if (!XL.Visible) XL.Visible = true; XL.ActiveWorkbook.Saved = true;}// System.Runtime.InteropServices.Marshal.ReleaseComObject(XL); XL = null; GC.GetTotalMemory(true); // вызов сборщика мусора// Пока не закрыть приложение EXCEL.EXE будет висеть в процессах}}public void export\_to\_exel()// Экспорт данных в Эксель (спижжено, без комментариев){ app = new Excel.Application(); app.Visible = false;//app.SheetsInNewWorkbook = 1;//обязательно до создания новой книги//var workbook = app.Workbooks.Add(1); string path = Environment.CurrentDirectory + "\\flot\_list.xlsx"; string sheet\_name\_d = DateTime.Now.ToString(); var temp\_time = new Regex(":");Excel.Workbook workbook;Excel.Worksheet worksheets; sheet\_name\_d = temp\_time.Replace(sheet\_name\_d, ".");if(File.Exists(path) == false){ workbook = app.Workbooks.Add(Environment.CurrentDirectory + "\\flot\_list\_template"); workbook.SaveAs(Environment.CurrentDirectory + "\\flot\_list.xlsx");} workbook = app.Workbooks.Open(path); worksheets = app.Worksheets.Add(); worksheets.Name = sheet\_name\_d; app.Columns.ColumnWidth = 17; app.Cells[1, 2] = "Никнейм";// Стартовые значения заголовков таблицы app.Cells[1, 1] = "uID"; app.Cells[1, 3] = "Корпорация"; app.Cells[1, 4] = "Тэг"; app.Cells[1, 5] = "Сыграно битв [x1000]"; app.Cells[1, 6] = "Винрейт"; app.Cells[1, 7] = "Убийств [x100000]"; app.Cells[1, 8] = "Убийств за бой"; app.Cells[1, 9] = "Убийств" + " / " + "Сметрей"; app.Cells[1, 10] = "Помощи за бой"; app.Cells[1, 11] = "Урона за бой [x100000]"; app.Cells[1, 12] = "Лечения за бой [x100000]"; app.Cells[1, 13] = "Карма пилота [x100000]"; app.Cells[1, 14] = "Мощь флота [x10]";for (int i = 0; i \< dataGridView1.Rows.Count; i++){for (int j = 0; j \< dataGridView1.ColumnCount; j++){ app.Cells[i + 2, j + 1] = dataGridView1.Rows[i].Cells[j].Value; app.Cells[i + 2, 5]=double.Parse (dataGridView1.Rows[i].Cells[4].Value.ToString()) / 1000; app.Cells[i + 2, 7] =double.Parse (dataGridView1.Rows[i].Cells[6].Value.ToString()) / 100000; app.Cells[i + 2, 11] =double.Parse (dataGridView1.Rows[i].Cells[10].Value.ToString()) / 100000; app.Cells[i + 2, 12] =double.Parse (dataGridView1.Rows[i].Cells[11].Value.ToString()) / 100000; app.Cells[i + 2, 13] =double.Parse (dataGridView1.Rows[i].Cells[12].Value.ToString()) / 100000; app.Cells[i + 2, 14] =double.Parse (dataGridView1.Rows[i].Cells[13].Value.ToString()) / 10;}}int z = dataGridView1.Rows.Count + 1;//Если бы мы открыли несколько книг, то получили ссылку так//excelappworkbook=excelappworkbooks[1];//Получаем массив ссылок на листы выбранной книги excelsheets = workbook.Worksheets;//Получаем ссылку на лист 1 excelworksheet = (Excel.Worksheet)excelsheets.get\_Item(1);//Выделяем ячейки с данными в таблице excelcells = excelworksheet.get\_Range("b1", "n" + z);//И выбираем их excelcells.Select();//Создаем объект Excel.Chart диаграмму по умолчаниюExcel.Chart excelchart = (Excel.Chart)app.Charts.Add();//Выбираем диграмму - отображаем лист с диаграммой excelchart.Activate(); excelchart.Select(Type.Missing);//Изменяем тип диаграммы app.ActiveChart.ChartType = Excel.XlChartType.xlLine;//Создаем надпись - Заглавие диаграммы app.ActiveChart.HasTitle = true; app.ActiveChart.ChartTitle.Text = "Cтатистика космофлота"; app.Visible = true; app.UserControl = true;FinishExcel(app);}public void export\_to\_xml()// Экспорт данных в .xml файл{DataSet ds = new DataSet(); // создаем пока что пустой кэш данныхSystem.Data.DataTable dt = new System.Data.DataTable(); // создаем пока что пустую таблицу данных dt.TableName = "pilot"; // название таблицы// название колонок dt.Columns.Add("Никнейм"); dt.Columns.Add("uID"); dt.Columns.Add("Корпорация"); dt.Columns.Add("Тэг"); dt.Columns.Add("Сыграно битв"); dt.Columns.Add("Винрейт"); dt.Columns.Add("Убийств"); dt.Columns.Add("Убийств за бой"); dt.Columns.Add("Убийств Смертей"); dt.Columns.Add("Помощи за бой"); dt.Columns.Add("Урона за бой"); dt.Columns.Add("Лечения за бой"); dt.Columns.Add("Карма пилота"); dt.Columns.Add("Мощь флота"); ds.Tables.Add(dt); //в ds создается таблица, с названием и колонками, созданными выше foreach (DataGridViewRow r in dataGridView1.Rows) // пока в dataGridView1 есть строки{DataRow row = ds.Tables["pilot"].NewRow(); // создаем новую строку в таблице, занесенной в ds row["Никнейм"] = r.Cells[1].Value;//в столбец этой строки заносим данные из первого столбца dataGridView1 row["uID"] = r.Cells[0].Value; row["Корпорация"] = r.Cells[2].Value; row["Тэг"] = r.Cells[3].Value; row["Сыграно битв"] = r.Cells[4].Value; row["Винрейт"] = r.Cells[5].Value; row["Убийств"] = r.Cells[6].Value; row["Убийств за бой"] = r.Cells[7].Value; row["Убийств Смертей"] = r.Cells[8].Value; row["Помощи за бой"] = r.Cells[9].Value; row["Урона за бой"] = r.Cells[10].Value; row["Лечения за бой"] = r.Cells[11].Value; row["Карма пилота"] = r.Cells[12].Value; row["Мощь флота"] = r.Cells[13].Value; ds.Tables["pilot"].Rows.Add(row); //добавление всей этой строки в таблицу ds.} ds.WriteXml("fleet\_data.xml");}public void export\_to\_csv()// Экспорт данных в .csv файл{ string fileCSV = ""; saveFileDialog1.Filter = "Файлы csv|\*.csv"; saveFileDialog1.ShowDialog();for (int f = 0; f \< dataGridView1.ColumnCount; f++){ fileCSV += (dataGridView1.Columns[f].HeaderText + ";");} fileCSV += "\t\n"; //тут была загвоздкаfor (int i = 0; i \< dataGridView1.RowCount ; i++){for (int j = 0; j \< dataGridView1.ColumnCount; j++){ fileCSV += (dataGridView1[j, i].Value).ToString() + ";";} fileCSV += "\t\n";}StreamWriter wr = new StreamWriter(saveFileDialog1.FileName, false, System.Text.Encoding.GetEncoding("windows-1251")); wr.Write(fileCSV); wr.Close();}public void clear\_data()// Функция очистки таблицы с данными{ dataGridView1.Rows.Clear(); load\_to\_csv\_button.Enabled = false; load\_to\_exel\_button.Enabled = false; load\_to\_xml\_button.Enabled = false;}private void new\_pilots\_Click(object sender, EventArgs e){ clear\_data(); new\_file\_dialog(); load\_to\_datagridview\_table.Enabled = true;}private void find\_file\_Click(object sender, EventArgs e){FocusFile(pilots\_list);}private void open\_file\_Click(object sender, EventArgs e){ open\_file\_dialog();}private void load\_to\_datagridview\_table\_Click(object sender, EventArgs e){ clear\_data(); load\_data();}private void clean\_data\_Click(object sender, EventArgs e){ clear\_data();}private void clean\_flot\_initialize\_Click(object sender, EventArgs e){ clean\_flot\_realization.Enabled = true;}private void clean\_flot\_realization\_Click(object sender, EventArgs e){ clean\_flot();}private void load\_to\_exel\_button\_Click(object sender, EventArgs e){ export\_to\_exel();}private void load\_to\_xml\_button\_Click(object sender, EventArgs e){ export\_to\_xml();DialogResult result = MessageBox.Show("Таблица экспортирована \nОткрыть расположение таблицы?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Question);if (result == DialogResult.Yes){System.Diagnostics.Process.Start("explorer.exe", @"/select, " + "fleet\_data.xml");}}private void load\_to\_csv\_button\_Click(object sender, EventArgs e){ export\_to\_csv();}private void MainForm\_FormClosing(object sender, FormClosingEventArgs e){FinishExcel(app);}private void MainForm\_FormClosed(object sender, FormClosedEventArgs e){FinishExcel(app);}}}
Само приложение:
https://yadi.sk/d/0ibjiZ20vfLkw или прикрепленный архив:
апдейты:
Скрытый текст