- •Описание записи (record).
- •Работа с файлами. Общие сведения о файлах.
- •Процедуры и функции для работы с файлами.
- •Особенности обработки типизированных файлов.
- •Создание файла.
- •3. Добавление записей к файлу (в конец файла)
- •If { корректировка подтверждена }
- •If {…запись не удаляется…}
- •Корректировка с использованием последовательного доступа.
- •If {запись не корректируется}
- •О взаимосвязи записей основного обрабатываемого файла и записей файлов-справочников
- •Файлы без типа.
If {…запись не удаляется…}
then write (f_temp, zap)
else {запись не выводится в файл f_temp,
либо, например, пишется в другой
файл};
until eof(f1);
close(f1);
close (f_temp);
. . .
Корректировка с использованием последовательного доступа.
Перед выполнением корректировки пользователь должен увидеть содержимое файла и выбрать запись для корректировки, например, запомнив её порядковый (логический) номер.
Корректировка выполняется по технологии, схожей с технологией удаления записей. Открывается основной файл, и его записи переписываются в новый файл последовательным доступом. При этом каждая прочитанная запись контролируется – должна ли она быть скорректирована. Если нет, то она переписывается в новый файл. Если да, то не переписывается, а корректируется.
{ корректировка записей файла f1 }
. . .
reset(f1);
rewrite (F_temp);
repeat
read(f1,zap);
If {запись не корректируется}
then write (f_temp, zap)
else {запись корректируется}
begin
{ 1. исх. запись zap копируется
в поле zap_corr}
{ 2. пользователь корректирует}
{ поля записи в zap_corr }
{ 3. затем у пользователя }
{ запрашивается подтверждение}
{ сделанной корректировки}
If { корректировка подтверждена }
then {в файл записываеся
откорректированная
запись zap_corr }
write (f_temp, zap_corr)
else {в файл записывается
исходная запись zap}
write (f_temp, zap);
end;
until eof(f1);
close(f1);
close (f_temp);
. . .
Пользователь должен подтвердить корректировку или отказаться от неё. Перед подтверждением пользователь должен увидеть тексты старой, исходной и новой, откорректированной записей. Только после этого он принимает решение о подтверждении сделанной корректировки или отказе от неё. Лучший вариант – возможность видеть одновременно и прежнее, и новое значения полей.
После закрытия файлов возможны следующие варианты:
а) старый файл уничтожается, а новый файл получает имя старого файла;
б) старый файл сохраняет прежнее имя, но получает новое расширение ~.BAK, а новый файл получает имя старого файла;
в) содержимое нового файла переписывается в старый файл, новый файл уничтожается.
Корректировка с использованием прямого доступа:
определяется корректируемая запись;
значение ключевого признака корректируемой записи преобразуется в номер физической записи в файле;
указатель записи позиционируется на искомую запись процедурой Seek (имя_файла_прогр, номер_записи);
искомая запись читается в оперативную память с использованием Read (имя_файла_прогр, поле_записи);
выполняется корректировка полей записи;
указатель вновь позиционируется (возвращается) на корректируемую запись процедурой
Seek (имя_файла_прогр, номер_записи);
либо
Seek (имя_файла_прогр, (FilePos ( имя_файла_прогр ) - 1); {возврат с текущей записи на предыдущую}
7) вывод откорректированной записи в файл на своё прежне место
Write (имя_файла_пр, поле_записи);
Внимание: здесь тоже необходимо подтверждать выполнение сделанной корректировки
Работа с файлом с использованием оперативной памяти.
Эта технология может быть применена при обработке файлов относительно небольших размеров.
Если объём оперативной памяти и объём файла позволяют, то схема обработки типизированного файла может выглядеть следующим образом.
Исходя из количества записей, выделяется динамическая память под массив записей.
Записи файла переносятся в массив.
Над массивом записей в оперативной памяти выполняются требуемые действия (заполнение, добавление, удаление, корректировка), но реализуемые алгоритмами работы с массивом.
После окончания обработки массив записывается в новый файл (желательно, чтобы пользователь подтвердил сделанные изменения).
Принимается решение о варианте использования нового файла в совокупности с основным (переименование в основной файл, перепись в основной и удаление и т.д.).
Внимание! Только один этот вариант работы с файлами в лабораторных работах № 1 и № 2 использован быть не может. Необходимо применить варианты использования рабочего файла.
Особенности обработки текстовых файлов.
Текстовые файлы состоят из символов. Каждый текстовый файл разделяется на строки неопределенной длины, которые заканчиваются символом конец строки. Весь файл заканчивается символом «конец файла».
К текстовым файлам возможен только последовательный доступ. С текстовыми файлами работают различные редакторы текстов. Текстовые файлы имеют стандартный тип TEXT.
VAR
Имя_файла: TEXT;
Посимвольные операции ввода-вывода выполняются для текстовых файлов процедурами read и write.
Строки (логические записи) вводятся и выводятся специальными процедурами для текстовых файлов readln и writeln.
|
Кроме того, для текстовых файлов применяются процедуры ASSIGN, RESET, REWRITE, CLOSE, EOF, eoln.
Процедура append открывает существующий текстовый файл для добавления записей.
Для текстовых файлов нельзя использовать процедуры и функции SEEK, FILEPOS, FILESIZE, т.к. элементы (записи текстового файла) имеют разную длину.
input и output стандартные текстовые файлы для ввода с клавиатуры и вывода на экран.
Рекомендация: при вводе/выводе преимущественно использовать процедуры READLN ( ) и WRITELN ( );
Пример
Рассмотрим программу, реализующую следующую задачу. Дан текстовый файл F1.Необходимо заменить во всех записях этого файла код группы ДКЕ-101 на ДКЕ-201. Скорректированные записи поместить в файл F2.
var
f1,f2: text;
pole:string;
filename, filenam2:string[12];
pz: integer;
begin
write(‘ввод имени входного файла:’);
readln(filename);
assign(f1, filename);
reset(f1); { без защиты }
write(‘ввод имени выходного файла:’);
readln(filenam2);
assign(f2, filenam2);
rewrite(f2);
while ( not eof(f1) ) do
begin
readln(f1,pole);
while ( pos(‘дке-101’, pole) ) <> 0 do
begin
pz:= pos(‘дке-101’, pole);
delete(pole,pz+4,1);
insert(‘2’,pole,pz+4);
end;
writeln(f2,pole)
end;
close(f1);
close(f2);
end.
Здесь читаются последовательно строки из входного файла и в каждой строке в номере группы заменяется символ 1 на 2. Скорректированные строки выводятся в новый файл.
Работа с типизированным файлом прямым доступом
При прямом доступе сначала вычисляется значение указателя, определяющего номер записи (номер компонента), после чего можно обеспечить прямой доступ к нужной записи, используя процедуру позиционирования
SEEK (имя_файла_в_прог , физ_номер_записи) ;
Далее может следовать:
либо чтение указанной записи из файла,
либо занесение подготовленной записи в файл на указанное место вместо прежней записи (примерно так может быть выполнена корректировка или замена указанной записи в файле).
Для обеспечения прямого доступа необходимо следующее:
файл должен быть типизированным (фиксированная, постоянная длина записи);
данные (записи файла) располагаются в областях на диске, имеющих последовательные номера (нумерация областей, начиная с нуля, осуществляется автоматически);
обратить внимание: первая логическая запись будет размещена в физической области с нулевым номером, вторая логическая – в первой физической и т.д. В Seek (…) указывается физический номер записи
размещение записей желательно без пропусков.
использование процедур, обеспечивающих
контроль положения указателя чтения FilePos (…);
позиционирование указателя чтения в файле Seek (…);
желательно (настоятельно рекомендуется) наличие в записи признака, преобразующегося в физический номер записи, так называемого ключа записи. Простейший метод преобразования значения ключа в номер записи:
Номер_зап = Ключ_тек – Ключ_мин
Возможны и более сложные алгоритмы преобразования значения признака из записи в физический номер записи в файле, но, так или иначе, необходимо наличие связи между ключом записи и её номером.
записи в файле должны быть рассортированы по ключевому признаку в порядке возрастания, если ключевой признак преобразуется в физический номер записи.
Не исключается вариант, когда значения ключевого признака записи образуют не строго последовательный ряд значений, а ряд с пропусками, пустотами. Чем больше таких пустот, тем более неэффективной будет работа с таким файлом. Наличие таких пустот приведёт к следующим недостаткам:
потери в используемой памяти («пустые» записи внутри файла);
необходимо выполнить предварительное резервирование места для записей – что-то вроде разметки файлового пространства, то есть занесение в файл только пустых записей;
заполнение файла реальными записями в файл прямым доступом в соответствии со значениями их ключей;
контроль записей при чтении из файла, чтобы не работать с пустыми записями.
Пример.
В следующей программе, используя прямой доступ к записям файла, созданного в предыдущей программе, требуется подсчитать общую сумму зарплаты тех рабочих, чьи табельные номера вводятся с клавиатуры. Предполагается, что при создании файла были использованы табельные номера в интервале 101-999 и запись с номером 101 занимает первое место в файле, за ней следует запись с табельным номером 102 и т.д. Таким образом, табельный номер и есть ключ записи, который будет преобразован в физический номер записи
program file_2;
type
tz=record
fio:string[20];
tn:integer;
zp:real
end;
var
zap:tz;
fout:file of tz;
tn1,tn2,n:integer;
s:real;
filename:string;
ans : string;
begin
writeln('введите имя файла ');
readln(filename);
assign (fout, filename);
reset(fout);
s:=0;
repeat
readln(tn2);
tn1:=tn2-101;
{формирование указателя записи,
101 – это минимальное значение табельного номера}
seek(fout,tn1);
read(fout,zap);
s:=s+zap.zp;
writeln('ещё запрос ? ( y/ n )');
readln(ans);
until ( ans = ‘n’ );
writeln(‘s= ‘,s);
close(fout)
end.
ВНИМАНИЕ: в задаче нет многих подстраховок: от ввода пустой строки, от несуществующего файла и др.
Материал к лабораторной работе по файлам
Подведение итога по файлу (одной степени).
Код цеха |
Код участка |
Таб.номер |
Кол-во |
Расценка за единицу |
Начислено |
1 |
1 |
111 |
10 |
10 |
100 |
1 |
1 |
111 |
11 |
10 |
110 |
1 |
1 |
111 |
10 |
2 |
20 |
1 |
1 |
111 |
5 |
5 |
25 |
1 |
1 |
111 |
12 |
5 |
60 |
1 |
1 |
120 |
2 |
2 |
4 |
1 |
1 |
120 |
5 |
2 |
10 |
1 |
1 |
120 |
3 |
3 |
9 |
1 |
1 |
120 |
10 |
5 |
50 |
1 |
1 |
120 |
5 |
10 |
50 |
1 |
2 |
130 |
100 |
1 |
100 |
1 |
2 |
130 |
110 |
2 |
220 |
1 |
2 |
130 |
100 |
1 |
100 |
1 |
2 |
130 |
5 |
50 |
250 |
1 |
2 |
130 |
120 |
2 |
240 |
1 |
2 |
135 |
20 |
2 |
40 |
1 |
2 |
135 |
5 |
20 |
100 |
1 |
2 |
135 |
3 |
30 |
90 |
1 |
2 |
135 |
10 |
5 |
50 |
1 |
2 |
135 |
10 |
10 |
100 |
2 |
10 |
200 |
10 |
20 |
200 |
2 |
10 |
200 |
11 |
10 |
110 |
2 |
10 |
200 |
10 |
2 |
20 |
2 |
10 |
200 |
5 |
5 |
25 |
2 |
10 |
200 |
12 |
5 |
60 |
2 |
10 |
250 |
2 |
2 |
4 |
2 |
10 |
250 |
5 |
2 |
10 |
2 |
10 |
250 |
3 |
3 |
9 |
2 |
10 |
250 |
10 |
5 |
50 |
2 |
10 |
250 |
5 |
10 |
50 |
2 |
20 |
130 |
100 |
1 |
100 |
2 |
20 |
130 |
110 |
2 |
220 |
2 |
20 |
130 |
100 |
1 |
100 |
2 |
20 |
130 |
5 |
50 |
250 |
2 |
20 |
130 |
120 |
2 |
240 |
2 |
2 |
135 |
20 |
2 |
40 |
2 |
2 |
135 |
5 |
20 |
100 |
2 |
2 |
135 |
3 |
30 |
90 |
2 |
2 |
135 |
10 |
5 |
50 |
2 |
2 |
135 |
10 |
10 |
100 |
|
|
|
|
|
|
Итого по заводу |
|
|
|
|
3556 |
Type
Rec = record
Code_z : integer;
Code_uch : integer;
Tab_nom : integer;
Kol_vo : integer;
Rasz : real;
End;
Var
Zap : rec;
Sum_file : real;
Begin
Writeln (‘ Введите имя файла на диске: ‘);
Readln (Filename)’
Assign (Mainfile, filename);
Reset (mainfile);
Sum_file := 0;
While (not EOF (mainfile)) do
Begin
Read (Mainfile, zap);
Nachisl := zap.kol_vo * zap.rasz;
Sum_file := sum_file + nachisl;
End;
Writeln (‘ Итого по заводу начислено ‘,
Sum_file:10:2);
Readln;
End.
Подведение итога по по цехам и по файлу/заводу
(итоги двух степеней).
Код цеха |
Код участка |
Таб.номер |
Кол-во |
Расценка за единицу |
Начислено |
1 |
1 |
111 |
10 |
10 |
100 |
1 |
1 |
111 |
11 |
10 |
110 |
1 |
1 |
111 |
10 |
2 |
20 |
1 |
1 |
111 |
5 |
5 |
25 |
1 |
1 |
111 |
12 |
5 |
60 |
1 |
1 |
120 |
2 |
2 |
4 |
1 |
1 |
120 |
5 |
2 |
10 |
1 |
1 |
120 |
3 |
3 |
9 |
1 |
1 |
120 |
10 |
5 |
50 |
1 |
1 |
120 |
5 |
10 |
50 |
1 |
2 |
130 |
100 |
1 |
100 |
1 |
2 |
130 |
110 |
2 |
220 |
1 |
2 |
130 |
100 |
1 |
100 |
1 |
2 |
130 |
5 |
50 |
250 |
1 |
2 |
130 |
120 |
2 |
240 |
1 |
2 |
135 |
20 |
2 |
40 |
1 |
2 |
135 |
5 |
20 |
100 |
1 |
2 |
135 |
3 |
30 |
90 |
1 |
2 |
135 |
10 |
5 |
50 |
1 |
2 |
135 |
10 |
10 |
100 |
Итого по цеху 1 |
|
|
|
|
1728 |
|
|
|
|
|
|
2 |
10 |
200 |
10 |
20 |
200 |
2 |
10 |
200 |
11 |
10 |
110 |
2 |
10 |
200 |
10 |
2 |
20 |
2 |
10 |
200 |
5 |
5 |
25 |
2 |
10 |
200 |
12 |
5 |
60 |
2 |
10 |
250 |
2 |
2 |
4 |
2 |
10 |
250 |
5 |
2 |
10 |
2 |
10 |
250 |
3 |
3 |
9 |
2 |
10 |
250 |
10 |
5 |
50 |
2 |
10 |
250 |
5 |
10 |
50 |
2 |
20 |
130 |
100 |
1 |
100 |
2 |
20 |
130 |
110 |
2 |
220 |
2 |
20 |
130 |
100 |
1 |
100 |
2 |
20 |
130 |
5 |
50 |
250 |
2 |
20 |
130 |
120 |
2 |
240 |
2 |
2 |
135 |
20 |
2 |
40 |
2 |
2 |
135 |
5 |
20 |
100 |
2 |
2 |
135 |
3 |
30 |
90 |
2 |
2 |
135 |
10 |
5 |
50 |
2 |
2 |
135 |
10 |
10 |
100 |
Итого по цеху 2 |
|
|
|
|
1828 |
|
|
|
|
|
|
Итого по заводу |
|
|
|
|
3556 |
Вариант 1 (необходимо особо учитывать случай обработки последней записи)
Type
Rec = record
Code_z : integer;
Code_uch : integer;
Tab_nom : integer;
Kol_vo : integer;
Rasz : real;
End;
Var
Zap : rec;
Sum_z, Sum_file : real;
Code_z : integer;
Begin
Writeln (‘ Введите имя файла на диске: ‘);
Readln (Filename)’
Assign (Mainfile, filename);
Reset (mainfile);
Sum_file := 0;
Read (Mainfile, zap);
While (not EOF (mainfile)) do
Begin
Code_z:=zap.code_z;
Sum_z := 0;
While (not EOF (mainfile)) and
(Code_z = zap.code_z) do
begin
Nachisl := zap.kol_vo * zap.rasz;
Sum_z := sum_z + nachisl;
Read (Mainfile, zap);
End;
Writeln (‘ Итого по цеху’, code_z,
‘ начислено ‘, Sum_file:10:2);
Sum_file := sum_file + Sum_z;
End;
Writeln (‘ Итого по заводу начислено ‘,
Sum_file:10:2);
Readln; End.
{ необходимо особо учитывать случай обработки последней записи}
Итоги трёх степеней
Код цеха |
Код участка |
Таб.номер |
Кол-во |
Расценка за единицу |
Начислено |
1 |
1 |
111 |
10 |
10 |
100 |
1 |
1 |
111 |
11 |
10 |
110 |
1 |
1 |
111 |
10 |
2 |
20 |
1 |
1 |
111 |
5 |
5 |
25 |
1 |
1 |
111 |
12 |
5 |
60 |
1 |
1 |
120 |
2 |
2 |
4 |
1 |
1 |
120 |
5 |
2 |
10 |
1 |
1 |
120 |
3 |
3 |
9 |
1 |
1 |
120 |
10 |
5 |
50 |
1 |
1 |
120 |
5 |
10 |
50 |
Итого по участку |
1 |
|
|
|
438 |
|
|
|
|
|
|
1 |
2 |
130 |
100 |
1 |
100 |
1 |
2 |
130 |
110 |
2 |
220 |
1 |
2 |
130 |
100 |
1 |
100 |
1 |
2 |
130 |
5 |
50 |
250 |
1 |
2 |
130 |
120 |
2 |
240 |
|
|
|
|
|
|
1 |
2 |
135 |
20 |
2 |
40 |
1 |
2 |
135 |
5 |
20 |
100 |
1 |
2 |
135 |
3 |
30 |
90 |
1 |
2 |
135 |
10 |
5 |
50 |
1 |
2 |
135 |
10 |
10 |
100 |
Итого по участку |
2 |
|
|
|
1290 |
|
|
|
|
|
|
Итого по цеху 1 |
|
|
|
|
1728 |
|
|
|
|
|
|
2 |
10 |
200 |
10 |
20 |
200 |
2 |
10 |
200 |
11 |
10 |
110 |
2 |
10 |
200 |
10 |
2 |
20 |
2 |
10 |
200 |
5 |
5 |
25 |
2 |
10 |
200 |
12 |
5 |
60 |
2 |
10 |
250 |
2 |
2 |
4 |
2 |
10 |
250 |
5 |
2 |
10 |
2 |
10 |
250 |
3 |
3 |
9 |
2 |
10 |
250 |
10 |
5 |
50 |
2 |
10 |
250 |
5 |
10 |
50 |
Итого по участку |
10 |
|
|
|
538 |
|
|
|
|
|
|
2 |
20 |
130 |
100 |
1 |
100 |
2 |
20 |
130 |
110 |
2 |
220 |
2 |
20 |
130 |
100 |
1 |
100 |
2 |
20 |
130 |
5 |
50 |
250 |
2 |
20 |
130 |
120 |
2 |
240 |
2 |
2 |
135 |
20 |
2 |
40 |
2 |
2 |
135 |
5 |
20 |
100 |
2 |
2 |
135 |
3 |
30 |
90 |
2 |
2 |
135 |
10 |
5 |
50 |
2 |
2 |
135 |
10 |
10 |
100 |
Итого по участку |
2 |
|
|
|
1290 |
|
|
|
|
|
|
Итого по цеху 2 |
|
|
|
|
1828 |
|
|
|
|
|
|
Итого по заводу |
|
|
|
|
3556 |
Type
Rec = record
Code_z : integer;
Code_uch : integer;
Tab_nom : integer;
Kol_vo : integer;
Rasz : real;
End;
Var
Zap : rec;
Sum_uch, Sum_z, Sum_file : real;
Code_uch, Code_z : integer;
Begin
Writeln (‘ Введите имя файла на диске: ‘);
Readln (Filename)’
Assign (Mainfile, filename);
Reset (mainfile);
Sum_file := 0;
Read (Mainfile, zap);
While (not EOF (mainfile)) do
Begin
Code_z:=zap.code_z;
Sum_z := 0;
While (not EOF (mainfile)) and
(Code_z = zap.code_z) do
begin
Code_uch:=zap.code_uch;
Sum_uch := 0;
While (not EOF (mainfile)) and
(Code_z = zap.code_z) and
(Code_uch = zap.code_uch)do
begin
Nachisl := zap.kol_vo * zap.rasz;
Sum_uch := sum_uch + nachisl;
Read (Mainfile, zap);
End;
Writeln (‘ Итого по участку’, code_uch,
‘ начислено ‘, Sum_uch:10:2);
Sum_z := sum_z + Sum_uch;
End;
Writeln (‘ Итого по цеху’, code_z,
‘ начислено ‘, Sum_z:10:2);
Sum_file := sum_file + Sum_z;
End;
Writeln (‘ Итого по заводу начислено ‘,
Sum_file:10:2);
Readln;
End.
Итоги четырёх степеней
Код цеха |
Код участка |
Таб.номер |
Кол-во |
Расценка за единицу |
Начислено |
1 |
1 |
111 |
10 |
10 |
100 |
1 |
1 |
111 |
11 |
10 |
110 |
1 |
1 |
111 |
10 |
2 |
20 |
1 |
1 |
111 |
5 |
5 |
25 |
1 |
1 |
111 |
12 |
5 |
60 |
|
Итого по таб.номеру 111 |
|
|
315 |
|
|
|
|
|
|
|
1 |
1 |
120 |
2 |
2 |
4 |
1 |
1 |
120 |
5 |
2 |
10 |
1 |
1 |
120 |
3 |
3 |
9 |
1 |
1 |
120 |
10 |
5 |
50 |
1 |
1 |
120 |
5 |
10 |
50 |
|
Итого по таб.номеру 120 |
|
|
123 |
|
|
|
|
|
|
|
|
Итого по участку 1 |
|
|
|
438 |
|
|
|
|
|
|
1 |
2 |
130 |
100 |
1 |
100 |
1 |
2 |
130 |
110 |
2 |
220 |
1 |
2 |
130 |
100 |
1 |
100 |
1 |
2 |
130 |
5 |
50 |
250 |
1 |
2 |
130 |
120 |
2 |
240 |
|
Итого по таб.номеру 130 |
|
|
910 |
|
|
|
|
|
|
|
1 |
2 |
135 |
20 |
2 |
40 |
1 |
2 |
135 |
5 |
20 |
100 |
1 |
2 |
135 |
3 |
30 |
90 |
1 |
2 |
135 |
10 |
5 |
50 |
1 |
2 |
135 |
10 |
10 |
100 |
|
Итого по таб.номеру 135 |
|
|
380 |
|
|
Итого по участку 2 |
|
|
|
1290 |
Итого по цеху 1 |
|
|
|
|
1728 |
|
|
|
|
|
|
2 |
10 |
200 |
10 |
20 |
200 |
2 |
10 |
200 |
11 |
10 |
110 |
2 |
10 |
200 |
10 |
2 |
20 |
2 |
10 |
200 |
5 |
5 |
25 |
2 |
10 |
200 |
12 |
5 |
60 |
|
Итого по таб.номеру 200 |
|
|
415 |
|
|
|
|
|
|
|
2 |
10 |
250 |
2 |
2 |
4 |
2 |
10 |
250 |
5 |
2 |
10 |
2 |
10 |
250 |
3 |
3 |
9 |
2 |
10 |
250 |
10 |
5 |
50 |
2 |
10 |
250 |
5 |
10 |
50 |
|
Итого по таб.номеру 250 |
|
|
123 |
|
|
Итого по участку 10 |
|
|
|
538 |
|
|
|
|
|
|
2 |
20 |
130 |
100 |
1 |
100 |
2 |
20 |
130 |
110 |
2 |
220 |
2 |
20 |
130 |
100 |
1 |
100 |
2 |
20 |
130 |
5 |
50 |
250 |
2 |
20 |
130 |
120 |
2 |
240 |
|
Итого по таб.номеру 130 |
|
|
910 |
|
|
|
|
|
|
|
2 |
2 |
135 |
20 |
2 |
40 |
2 |
2 |
135 |
5 |
20 |
100 |
2 |
2 |
135 |
3 |
30 |
90 |
2 |
2 |
135 |
10 |
5 |
50 |
2 |
2 |
135 |
10 |
10 |
100 |
|
Итого по таб.номеру 135 |
|
|
380 |
|
|
Итого по участку 2 |
|
|
|
1290 |
Итого по цеху 2 |
|
|
|
|
1828 |
|
|
|
|
|
|
Итого по файлу (заводу) |
|
|
|
3556 |
|
