Форум программистов, компьютерный форум, киберфорум
Наши страницы
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
 
SHD1
0 / 0 / 1
Регистрация: 14.02.2016
Сообщений: 20
#1

RichEdit - запись строки и сохранение - Delphi

22.02.2016, 23:09. Просмотров 1044. Ответов 17

Помогите пожалуйста, снова с RichEdit.
Есть форма свидетельства:
RichEdit - запись строки и сохранение
Эта форма в формате RTF загружается в RichEdit (на форме 2).
Программа берёт данные из файла Excel, затем при выборе прибора данные из ячеек соответствующей таблицы записываются в RichEdit, но при этом форма видоизменяется - подчеркивания (которые были в форме) слезают на новые строки, а если строка не полностью заполняется, то подчеркивается только то, что копируется из таблицы (нижнее подчеркивание текста в коде реализовано). И при сохранении файла в том же формате изначальное форматирование текста слетает.
Скажите, можно ли сделать так, чтобы форма заполнялась правильно? Так, как в шаблоне, без смещений и потери формата. И чтобы потом это можно было распечатать на А5 формате и сохранить в файл новый.
Ниже архив с программой и код для кнопки заполнения RichEdit (немного урезанный, только для первой таблицы, потому что больше не влезло):
METR-SV.7z
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
procedure TForm1.Button2Click(Sender: TObject);
Var
 i,j:integer;
 s,f,g,k,h,t:string;
begin
form2.RichEdit1.Lines.LoadFromFile('C:\METR-SV\sv.rtf');
begin
with ListBox1 do
 begin
   if ItemIndex >= 0 then
     begin
     form2.Show;
     edit1.Text:=listbox1.Items[listbox1.itemindex];
     end
   else
    ShowMessage('Выберите СИ');
 end;
begin
if combobox1.Text='КФК' then
begin
  With StringGrid1 do
  begin
    for i:=0 to ColCount-1 do
      begin
        for j:=0 to RowCount-1 do
          begin
            if Cells[i,j]= Edit1.text then
            begin
            s:=StringGrid1.Cells[0,j];
            g:=StringGrid1.Cells[1,j];
            k:=StringGrid1.Cells[3,j];
            h:=StringGrid1.Cells[4,j];
            t:=StringGrid1.Cells[5,j];
             form2.richedit1.Lines.Strings[6]:=('СВИДЕТЕЛЬСТВО № ' + edit2.Text);
                  form2.RichEdit1.SelStart:=pos(edit2.Text,form2.RichEdit1.Text)-1;
                 form2.RichEdit1.SelLength:=length(edit2.Text);
                 form2.RichEdit1.SelAttributes.Style:=form2.RichEdit1.SelAttributes.Style+[fsUnderline];
             form2.richedit1.Lines.Strings[13]:=('Средство измерения ' + s + ' ' + g + ', ' + 'рег. № ' + k);
                  form2.RichEdit1.SelStart:=pos(s,form2.RichEdit1.Text)-1;
                 form2.RichEdit1.SelLength:=length(s);
                 form2.RichEdit1.SelAttributes.Style:=form2.RichEdit1.SelAttributes.Style+[fsUnderline];
                  form2.RichEdit1.SelStart:=pos('рег. № ',form2.RichEdit1.Text)-1;
                 form2.RichEdit1.SelLength:=length('рег. № ');
                 form2.RichEdit1.SelAttributes.Style:=form2.RichEdit1.SelAttributes.Style+[fsUnderline];
                  form2.RichEdit1.SelStart:=pos(', ',form2.RichEdit1.Text)-1;
                 form2.RichEdit1.SelLength:=length(', ');
                 form2.RichEdit1.SelAttributes.Style:=form2.RichEdit1.SelAttributes.Style+[fsUnderline];
                  form2.RichEdit1.SelStart:=pos(g,form2.RichEdit1.Text)-1;
                 form2.RichEdit1.SelLength:=length(g);
                 form2.RichEdit1.SelAttributes.Style:=form2.RichEdit1.SelAttributes.Style+[fsUnderline];
                  form2.RichEdit1.SelStart:=pos(k,form2.RichEdit1.Text)-1;
                 form2.RichEdit1.SelLength:=length(k);
                 form2.RichEdit1.SelAttributes.Style:=form2.RichEdit1.SelAttributes.Style+[fsUnderline];
             form2.richedit1.Lines.Strings[22]:=('Поверено в соответствии с ' + h);
                  form2.RichEdit1.SelStart:=pos(h,form2.RichEdit1.Text)-1;
                 form2.RichEdit1.SelLength:=length(h);
                 form2.RichEdit1.SelAttributes.Style:=form2.RichEdit1.SelAttributes.Style+[fsUnderline];
             form2.richedit1.Lines.Strings[25]:=('С применением эталонов ' + t);
                  form2.RichEdit1.SelStart:=pos(t,form2.RichEdit1.Text)-1;
                 form2.RichEdit1.SelLength:=length(t);
                 form2.RichEdit1.SelAttributes.Style:=form2.RichEdit1.SelAttributes.Style+[fsUnderline];
            Exit;
            end;
          end;
      end;
  end;
end;
 
 
end;
end;
end;
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.02.2016, 23:09
Я подобрал для вас темы с готовыми решениями и ответами на вопрос RichEdit - запись строки и сохранение (Delphi):

Сохранение из RichEdit
Здравствуйте,мне нужно сохранить всю информацию,которая находить в РичЕдите,но...

сохранение RichEdit в Record
Возникла необходимость сохранить два RichEdit в Record с последующим...

Сохранение текста написанного в RichEdit
Хочу сохранить написанное. Нажимаю сохранить выходит ошибка: Cannot create file...

Сохранение текста с RichEdit в разные форматы
Здраствуйте. Подскажите как можно сохранить текст из RichEdit в текстовый...

Сохранение содержимого richedit в переменную вместе с настройками шрифта
Доброго времени суток. Есть программка, работает хорошо, но есть неувязочка....

Запись в txt с RichEdit
Здраствуйте. проблема вот такая. есть RichEdit, где я ввел текст, а мне в файл...

17
unifikator
490 / 348 / 229
Регистрация: 29.03.2015
Сообщений: 675
23.02.2016, 07:28 #2
Я сделал вывод в richedit с ровными строками. После сохранения документа, при открытии документа в этой программе, документ отображается правильно, но при открытии в Word строки смещаются. Сделал печать из программы, но не знаю, распечатается ли документ на 1 странице.
Если хотите, то можно сделать легче. Создайте форму заполнения в Word следующим образом. Удалите из старого документа знаки подчёркивания. И нарисуйте вместо них линии (в Word Вставка\Фигуры). Или можете оформить подчёркивание в виде ячеек таблицы с только нижними рамками. В нужных для заполнения строках введите слова-метки. И я их из Delphi в Word заменю на значения из таблицы.
Прилагаю изменённый проект на Delphi.
1
Вложения
Тип файла: zip METR-SV.zip (363.5 Кб, 5 просмотров)
SHD1
0 / 0 / 1
Регистрация: 14.02.2016
Сообщений: 20
23.02.2016, 11:33  [ТС] #3
unifikator,
Спасибо огромное Это то, что я хотел
- Только вот если текста получается много (если выбрать прибор из РЕО, например), то он не переносится на другую строку.
- Линии рисовать пробовал, только они не отображаются в RichEdit. Хотя, если будут печататься, то это не страшно.
Получается, что не нужно будет подчеркивать введенный текст, правильно?
- Добавил возможность дату ставить, можно ли сделать так, чтобы на следующей строке после "Действительно до" записывалась дата, предыдущая введенной? (если выставить 23 февраля 2016, то чтобы действительно было до 22 февраля 2017)
- И фамилия поверителя не записывается на нужном месте

Подчеркивания везде удалил, добавил линии.
А какие метки и как поставить? Имеется ввиду "Средство измерения " и тому подобное?

Архив прилагаю
METR-SV.7z
0
SHD1
0 / 0 / 1
Регистрация: 14.02.2016
Сообщений: 20
23.02.2016, 12:31  [ТС] #4
Как можно сделать проверку заполнения всех Edit, ComboBox и выделения строк всех ListBox? Чтобы сообщение появлялось, если что-то не выделено или не выбрано
0
unifikator
490 / 348 / 229
Регистрация: 29.03.2015
Сообщений: 675
23.02.2016, 14:11 #5
Сделал перенос текста на другую строку той же процедурой qwritetext. Сделал дату предыдущую введённой. Сделал запись фамилии поверителя на нужном месте с помощью процедуры qwritesign(qs:string;ql,qx,qn:integer);, где qs - фамилия, ql - номер строки, qx - позиция в строке, qn - который раз фамилия попадается в документе (qn = 0, если первый раз). Сделал проверку заполнения формы.
Прилагаю проект.
1
Вложения
Тип файла: zip METR-SV.zip (382.9 Кб, 2 просмотров)
unifikator
490 / 348 / 229
Регистрация: 29.03.2015
Сообщений: 675
23.02.2016, 14:17 #6
Лучше сделать программу заполняющую документ в Word. Для этого нужна форма наподобие приложенной. Вы можете попробовать заполнить её вручную и тогда Вы заметите, что знаки подчёркивания в ней при заполнении не переносятся на новую строку. Эта форма в Word сделана с помощью таблицы и выбором только нижней границы ячеек.
1
Вложения
Тип файла: docx 1.docx (25.7 Кб, 5 просмотров)
SHD1
0 / 0 / 1
Регистрация: 14.02.2016
Сообщений: 20
23.02.2016, 21:27  [ТС] #7
Цитата Сообщение от unifikator Посмотреть сообщение
Лучше сделать программу заполняющую документ в Word. Для этого нужна форма наподобие приложенной. Вы можете попробовать заполнить её вручную и тогда Вы заметите, что знаки подчёркивания в ней при заполнении не переносятся на новую строку. Эта форма в Word сделана с помощью таблицы и выбором только нижней границы ячеек.
Вложения
1.docx (25.7 Кб, 1 просмотров)
Т.е. сделать таблицу, как в этом примере, поставить метки, и при выполнении программы вместо этих меток будет заноситься текст? А сам документ будет виден?

Добавлено через 33 минуты
Цитата Сообщение от unifikator Посмотреть сообщение
Сделал перенос текста на другую строку той же процедурой qwritetext. Сделал дату предыдущую введённой. Сделал запись фамилии поверителя на нужном месте с помощью процедуры qwritesign(qs:string;ql,qx,qn:integer);, где qs - фамилия, ql - номер строки, qx - позиция в строке, qn - который раз фамилия попадается в документе (qn = 0, если первый раз). Сделал проверку заполнения формы.
Спасибо огромное
0
SHD1
0 / 0 / 1
Регистрация: 14.02.2016
Сообщений: 20
23.02.2016, 21:28  [ТС] #8
Цитата Сообщение от SHD1 Посмотреть сообщение
Для этого нужна форма наподобие приложенной.
Вот, сделал по примеру вашей формы
sv.docx
0
SHD1
0 / 0 / 1
Регистрация: 14.02.2016
Сообщений: 20
23.02.2016, 21:51  [ТС] #9
И вот справка по меткам и архив проекта.
METR-SV.7z
справка.txt
0
unifikator
490 / 348 / 229
Регистрация: 29.03.2015
Сообщений: 675
24.02.2016, 06:25 #10
Сделал заполнение из раздела КФК документа в Word. Переделал следующую дату.
1
Вложения
Тип файла: zip METR-SV.zip (413.6 Кб, 4 просмотров)
SHD1
0 / 0 / 1
Регистрация: 14.02.2016
Сообщений: 20
24.02.2016, 12:13  [ТС] #11
Цитата Сообщение от unifikator Посмотреть сообщение
Сделал заполнение из раздела КФК документа в Word. Переделал следующую дату.
Вложения
METR-SV.zip (413.6 Кб, 0 просмотров)
Спасибо огромное ещё раз, это круто
- Можно ли сделать перенос текста на другую строку (в другую ячейку таблицы шаблона), если не помещается весь текст? Чтобы не на следующую строку, а именно в строку следующую. На скриншоте видно, как съезжает форма
RichEdit - запись строки и сохранение
- Можно ли сделать так, чтобы документ Word показывался в программе, а не открывался в MS Word? Потому что свидетельства печатаются подряд, столько окон Word'овских открытых память сильно съедят, да и путаться будем
- Можно ли так же сделать вывод документов (из папки darkside) на вкладке Оборотная сторона свидетельства Form2.RichEdit2, соответственно если выбран определённый прибор?
К примеру, если выбран ЭКГ Schiller AT-1, то загружать файл 'C:\METR-SV\darkside\ЭКГ\Schiller AT-1, Schiller AT-2.docx', если Рефрактометр, то 'C:\METR-SV\darkside\Рефрактометр.docx'
Если совпадений не найдено (в папке ЭКГ, к примеру), то при выборе тип "ЭКГ" загрузить файл 'C:\METR-SV\darkside\ЭКГ\ECG.docx'
0
SHD1
0 / 0 / 1
Регистрация: 14.02.2016
Сообщений: 20
24.02.2016, 18:17  [ТС] #12
Есть ли возможность замены меток в открытом документе Word? Чтобы в программе выбрать другой прибор, нажать на кнопку, и в уже открытом документе ввелись новые данные? Тогда можно сделать всего четыре вызова четырёх документов: свидетельство о поверке, оборотная сторона, протокол и извещение. По идее, память не будет заполняться тогда
0
unifikator
490 / 348 / 229
Регистрация: 29.03.2015
Сообщений: 675
24.02.2016, 20:21 #13
Я сделал перенос длинного текста на другую строку. Для этого в Word делается метка для первой строки и метка для второй. И в программе вызывается процедура qreplace2(qn1,qn2,qv:string;qw:integer);, где qn1 - первая метка, qn2 - вторая метка, qv - текст для вставки, qw - длина строки в Word.
Если вывести документ Word на форме с помощью компонента TOleContainer, то при работе с документом выведется меню и панель с кнопками Word на всей верхней части формы программы поэтому вид программы будет испорчен.
Если запускать Word полностью, то его при печати можно сделать невидимым qword.visible:=false;. Текущий документ можно закрыть qWord.ActiveDocument.Close(0); и открыть новый qWord.Documents.Open(FileName:=qt,ReadOnly:=false);, где qt - имя файла. Поэтому окна Word память не съедят.
Я сделал, что если выбран "ЭКГ Schiller AT-1", то загружается файл для обратной стороны "Schiller AT-1.rtf", а если его нет, то "ECG.rtf".
Метки и так заменяются в открытом документе Word. Но для повторного заполнения документа, заполненный документ нужно будет закрыть и загрузить шаблон с метками заново.
Прилагаю проект с изменениями.
1
Вложения
Тип файла: zip METR-SV.zip (416.8 Кб, 2 просмотров)
SHD1
0 / 0 / 1
Регистрация: 14.02.2016
Сообщений: 20
24.02.2016, 21:39  [ТС] #14
unifikator,
Цитата Сообщение от unifikator Посмотреть сообщение
Я сделал перенос длинного текста на другую строку. Для этого в Word делается метка для первой строки и метка для второй. И в программе вызывается процедура qreplace2(qn1,qn2,qv:string;qw:integer);, где qn1 - первая метка, qn2 - вторая метка, qv - текст для вставки, qw - длина строки в Word.
Работает, но иногда весь текст переносится во вторую ячейку . А иногда он переносится, даже если есть место в первой строке

Цитата Сообщение от unifikator Посмотреть сообщение
Если вывести документ Word на форме с помощью компонента TOleContainer, то при работе с документом выведется меню и панель с кнопками Word на всей верхней части формы программы поэтому вид программы будет испорчен.
А можно два документа открыть разных одновременно: документ sv.docs и файл протокола (форму сделаю чуть позже, надо раздобыть их в приличном варианте), который частично тоже будет заполняться теми же данными по таким же меткам?

Цитата Сообщение от unifikator Посмотреть сообщение
Если запускать Word полностью, то его при печати можно сделать невидимым qword.visible:=false;. Текущий документ можно закрыть qWord.ActiveDocument.Close(0); и открыть новый qWord.Documents.Open(FileName:=qt,ReadOnly:=false);, где qt - имя файла. Поэтому окна Word память не съедят.
Цитата Сообщение от unifikator Посмотреть сообщение
Метки и так заменяются в открытом документе Word. Но для повторного заполнения документа, заполненный документ нужно будет закрыть и загрузить шаблон с метками заново.
Закрывать документ вручную? Т.е. закрыть окно Word, потом в программе выбрать новый прибор, и заново откроется MS Word, правильно? А как защиту сделать от попытки оформить свидетельство на другой прибор при открытом документе?

Цитата Сообщение от unifikator Посмотреть сообщение
если выбран "ЭКГ Schiller AT-1", то загружается файл для обратной стороны "Schiller AT-1.rtf", а если его нет, то "ECG.rtf"
Не работает, другой файл не загружается
Можно подряд перечислять все варианты выбора прибора и загрузки определенного файла?

Архив проекта:
METR-SV.7z
0
unifikator
490 / 348 / 229
Регистрация: 29.03.2015
Сообщений: 675
24.02.2016, 23:24 #15
У меня текст вроде бы переносится нормально. Я сделал более точный перенос. Что бы отрегулировать перенос нужно подобрать длину строк в Word. В событии TForm1.Button2Click(Sender: TObject); вначале задаются длина строки для средства измерений lsi:=650; и для влияющих факторов lfactor:=300;.
Можно открыть и заполнять два документа Word.
Закрывать документ вручную и создавать защиту не нужно. Я сделал так, что когда новый документ открывается в Word, то прежний закрывается. В конце программы Word закрывается.
Загрузка файлов для обратной стороны не работала потому, что нельзя было выбрать "ЭКГ Schiller AT-1" из приборов. Я сделал так, что при выборе "ЭКГ" в типе, а потом "SCHILLER CARDIOVIT AT-1" в модели, то загружается на обратную сторону "Schiller AT-1, Schiller AT-2.rtf", а если его нет, то "ECG.rtf". Также если выбрано "Рефрактометр" в типе, то загружается "Рефрактометр.rtf", а если "рН", то "рН-метр.rtf". Можно подряд перечислять все варианты выбора прибора и загрузки определенного файла, но лучше назвать файлы как приборы и загружать файлы одной инструкцией.
Прилагаю проект с изменениями.
1
Вложения
Тип файла: zip METR-SV.zip (460.3 Кб, 2 просмотров)
SHD1
0 / 0 / 1
Регистрация: 14.02.2016
Сообщений: 20
27.02.2016, 09:02  [ТС] #16
unifikator,
Цитата Сообщение от unifikator Посмотреть сообщение
Что бы отрегулировать перенос нужно подобрать длину строк в Word
- Пытался подобрать, но обязательно какой-нибудь прибор неправильно перенесётся Шаблон немного переделал, и там переносы не нужны. Как теперь их убрать?

Цитата Сообщение от unifikator Посмотреть сообщение
Можно открыть и заполнять два документа Word.
- Пытался выделить процедуру открытия Word и замены меток и прописать её для других кнопок (открытия протокола и извещения о непригодности), но потерпел поражение ввиду оооочень малых знаний (практически нулевых) в области подключения и работы с Word в Delphi (и с Excel тоже)
- Как прописать для каждой кнопки (кроме оборотной стороны) запуск процедуры открытия своего шаблона? При условии, что в Edit1 или ComboBox1 текст совпадёт с нужным - для каждого типа прибора свой шаблон (с проверкой, все ли поля заполнены).
- И так же заполнять "Извещение о непригодности" для выбранного прибора (с проверкой, все ли поля заполнены)
- В коде всё завязано на RichEdit1 на Form2, верно? Можно ли убрать вообще RichEdit1? Ибо он не нужен уже Там ещё и подчёркивания прописаны, но убрать их не получилось, компилятор говорит, что всё это нужно А код получается громоздким. На Form2 останется только RichEdit2, в который будут загружаться файлы оборотной стороны (это уже сделал). И печать.

Цитата Сообщение от unifikator Посмотреть сообщение
Закрывать документ вручную и создавать защиту не нужно. Я сделал так, что когда новый документ открывается в Word, то прежний закрывается. В конце программы Word закрывается.
- Это круто Только если случайно закрыть MS Word , то выход из программы и заполнение другого свидетельства невозможны Появляется ошибка "Сервер RPC недоступен"
Можно ли сделать так, чтобы при случайном закрытии Word программа всё равно закрывалась? И документы новые заполнялись?
- И при запуске программы также проверить, есть ли шаблоны Word (sv.docx, izv.docx, temp.docx, а также файлы протоколов) и Excel (111.xlsx), и если их нет, то просто сообщение показывалось "Нет такого-то шаблона". В коде это присутствует, но если нет шаблона Word, то следом за сообщением появляется ошибка "Acces violation at address 0047616F...". И если шаблонов нет, то программу запускать не нужно. Зачем она нужна, без шаблонов.
- Проверку наличия MS Word и Excel на компьютере можно сделать?


При запуске программы на одном из рабочих компьютеров появилась проблема - вначале появляется ошибка Excel

"AppName: excel.exe AppVer: 14.0.6112.5000 AppStamp:4e9b2bb3
ModName: msvbvm60.dll ModVer: 6.0.98.2 ModStamp:48038259
fDebug: 0 Offset: 000e47f2"

Затем открывается пустая книга. Но в программе все таблицы заполнены. Можно ли как-то это исправить без переустановки MS? В Google ошибку искал, но ничего не нашел

Архив проекта и данные:
METR-SV.7z

ошибка Excel.txt

Справка по извещению.txt

справка по протоколам.txt
0
unifikator
490 / 348 / 229
Регистрация: 29.03.2015
Сообщений: 675
27.02.2016, 22:12 #17
Убрал лишний код, в том числе переносы, и сократил всю программу с помощью новых функций.
Сделал обработку кнопок "Заполнить протокол" и "Заполнить извещение о непригодности".
Открытие шаблона осуществляется функцией function qopenword(qshablon,qtemp:string):boolean;, где qshablon - название шаблона в папке программы, qtemp - название заполненного шаблона. Если шаблона нет, то функция возвращает false, иначе true. Заполнение шаблона для определённого значения combobox1 осуществляет процедура procedure qreplaceallcom(f,t,c:string;s:tstringgrid);, где f - название шаблона в папке protokol, t - заполненный шаблон, c - значение combobox1, s - соответсвующий stringgrid. Заполнение шаблона для определённого значения edit1 осуществляет процедура procedure qreplaceallkfk(f,t,c:string);, где f - название шаблона в папке protokol, t - название заполненного шаблона, c - значение edit1 при значении combobox равном КФК. Наподобие этих процедур можно создать свои.
Убрал RichEdit1.
Теперь если программу запускать не из Delphi, а из папки, и закрыть вручную Word, то сообщения об ошибке не будет, и при дальнейшей работе Word откроется. Но запуская программу из Delphi, будет редко появляться сообщение об ошибке и выделяться строка кода. При этом нужно нажать клавишу F9 для дальнейшего продолжения работы программы.
Сделал проверку на наличие шаблона Excel. Если другие шаблоны не существуют, то при заполнении выходит сообщение об ошибки с указанием имени файла.
Сделал проверку на наличие MS Excel и MS Word.
Там где появляется ошибка Excel лучше переустановить Excel.
Прилагаю проект с изменениями.
1
Вложения
Тип файла: zip METR-SV.zip (936.1 Кб, 4 просмотров)
SHD1
0 / 0 / 1
Регистрация: 14.02.2016
Сообщений: 20
28.02.2016, 09:35  [ТС] #18
unifikator,
Спасибо огромное
0
28.02.2016, 09:35
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.02.2016, 09:35
Привет! Вот еще темы с решениями:

Сохранение форматирования RichEdit
Скажите , возможно ли сохранить форматированный текст из RichEdit в файл так,...

Richedit строки
В Richedit при добавлении строк внизу получается место около 2-х пустых строк...

Раскрасить строки в RichEdit
Подсчет чисел из диапазона min-max в RichEdit, вывод в Label: procedure...

RichEdit Строки и Столбцы
Доброе утро, подскажите, как сделать так чтобы в статус баре при нажатии на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru