Функция Seek Возвращает значение типа Long, определяющее текущее положение указателя чтения/записи внутри файла, открытого с помощью инструкции Open. Seek(номерФайла) Обязательный аргумент номерФайла является выражением типа Integer, содержащим допустимый номер файла. Функция Seek возвращает значение в интервале от 1 до 2 147 483 647 (т.е. 2^31 - 1) включительно. Ниже приведено описание значений, возвращаемых для каждого режима доступа к файлу. Режим | Возвращаемое значение | Random | Номер записи, которая будет считана или записана следующей. | Binary,Output,Append,Input | Номер байта, с которого начинается выполнение следующей операции ввода/вывода. Первому байту файла соответствует номер 1, второму 2 и т.п. | Функция Loc Возвращает значение типа Long, определяющее текущее положение указателя чтения/записи внутри открытого файла. Loc( номерФайла) Обязательный аргумент номерФайла типа Integer представляет любой допустимый номер файла. Ниже перечислены значения, возвращаемые для каждого режима файла: Режим | Возвращаемое значение | Random | Номер последней записи, считанной или записанной в этот файл. | Sequential | Номер текущего байта, деленный на 128. (Следует отметить, что значение, возвращаемое функцией Loc для файлов в режиме последовательного доступа, не является ни нужным, ни необходимым). | Binary | Номер последнего считанного или записанного байта. | Функция LOF Возвращает значение типа Long, представляющее размер в байт файла, открытого с помощью инструкции Open. LOF(номерФайла) Обязательный аргумент номерФайла является выражением типа Integer, содержащим допустимый номер файла. Для определения размера неоткрытого файла следует использовать функцию FileLen. Функция EOF Возвращает значение типа Integer содержащее логическое значение True при достижении конца файла. EOF(номерФайла) Обязательный аргумент номерФайла является выражением типа Integer, содержащим любой допустимый номер файла. С помощью функции EOF можно избежать ошибок, возникающих при попытках чтения или записи после достижения конца файла. Функция EOF возвращает значение False до тех пор, пока не будет достигнут конец файла. При использовании с файлами, открытыми в режиме Random или Binary, функция EOF возвращает значение True, если последней выполненной инструкции Get не удалось считать целую запись; в противном случае возвращается значение False. Для файлов, открытых для доступа в режиме Binary, попытка чтения файла с помощью функции Input до возвращения функцией EOF значения True приводит к ошибке. При чтении двоичных файлов с помощью функции Input следует вместо функции EOF использовать функции LOF и Loc или использовать с функцией EOF инструкцию Get. Инструкция Get Читает данные из открытого файла на диске в переменную. Get [#]номерФайла, [ номерЗаписи], имяПеременной номерФайла - Обязательный. Любой допустимый номер файла. номерЗаписи - Необязательный. Тип Variant (Long). Номер записи (для файлов в режиме Random) или номер байта (для файлов в режиме Binary), с которого следует начать чтение. имяПеременной - Обязательный. Допустимое имя переменной, в которую следует поместить считанные данные. Данные, считываемые с помощью инструкции Get, обычно записываются в файл с помощью инструкции Put. Первой записи (или байту) файла соответствует номер 1, второй (или второму) 2 и т.п. Если аргумент номерЗаписи опущен, читается запись (или байт), на которую был установлен указатель после выполнения последней инструкции Get или Put (или переведен при последнем вызове функции Seek). Наличие запятых-разделителей является обязательным, например: Get #4,,FileBuffer Для файлов, открытых в режиме Random, применимы следующие правила: ·Даже если длина данных, подлежащих чтению, меньше длины записи, указанной в предложении Len инструкции Open, инструкция Get начинает чтение каждой следующей записи с начала этой записи. Пространство между концом одной записи и началом следующей записи заполняется текущим содержимым буфера файла. Поскольку объем данных, используемых для заполнения, не может быть определен с достаточной степенью уверенности, рекомендуется, чтобы длина записи совпадала с длиной читаемых данных. ·Если данные считываются в строку переменной длины, инструкция Get сначала считывает 2-байтовый дескриптор, содержащий длину строки, а затем данные, которые следует поместить в эту переменную. Таким образом, длина записи, указанная в предложении Len инструкции Open, должна быть по крайней мере на 2 байта больше, чем фактическая длина этой строки. ·Если данные считываются в переменную Variant числового типа, инструкция Get сначала считывает 2 байта, указывающие подтип (VarType) этой переменной, а затем данные, которые следует поместить в эту переменную. Например, при чтении переменной Variant подтипа VarType 3 инструкция Get считывает 6 байт: 2 байта, указывающие подтип переменной Variant как VarType 3 (Long), и 4 байта, содержащие значение типа Long. Длина записи, указанная в предложении Len инструкции Open, должна по крайней мере на 2 байта превышать фактический размер, необходимый для размещения этой переменной. С помощью инструкции Get можно считать массив типа Variant с диска, однако нельзя прочитать скаляр типа Variant, содержащий массив. Кроме того, инструкцию Get нельзя использовать для чтения объектов с диска. ·Если данные считываются в переменную типа Variant подтипа VarType 8 (String), инструкция Get сначала считывает 2 байта, указывающие VarType, потом 2 байта, указывающие длину строки, а затем содержимое строки. Длина записи, указанная в предложении Len инструкции Open, должна быть по крайней мере на 4 байта больше, чем фактическая длина этой строки. ·Если данные считываются в динамический массив, инструкция Get сначала считывает дескриптор, длина которого равняется (2 + 8 * числоРазмерностей) байт. Длина записи, указанная в предложении Len инструкции Open , должна быть больше либо равна сумме всех байтов, необходимых для размещения массива данных и дескриптора массива. Например, для размещения описанного ниже массива требуется 118 байт Dim MyArray(1 To 5,1 To 10) As Integer 118 байт распределяются следующим образом: 18 для дескриптора (2 + 8 * 2) и 100 байт для данных (5 * 10 * 2). ·Если данные считываются в массив фиксированного размера, инструкция Get считывает только данные. Дескриптор не считывается. ·Если данные считываются в переменную любого другого типа (кроме строки переменной длины и переменной типа Variant), инструкция Get считывает только данные. Длина записи, указанная в предложении Len инструкции Open, должна быть больше либо равна длине данных, подлежащих считыванию. ·Инструкция Get считывает элементы определяемых пользователем типов так, будто это отдельные переменные, за исключением того, что пространство между элементами не заполняется текущим содержимым буфера файла. На диске динамический массив типа, определенного пользователем (записанный с помощью инструкции Put) предваряется дескриптором, длина которого равняется (2 + 8 * числоРазмерностей) байт. Длина записи, указанная в предложении Len инструкции Open, должна быть больше либо равна сумме всех байтов, необходимых для размещения отдельных элементов, в том числе, массивов и их дескрипторов. Для файлов, открытых в режиме Binary, применимы все перечисленные выше правила, за исключением следующих: ·Предложение Len инструкции Open игнорируется. Инструкция Get считывает все переменные с диска непрерывно, т.е. без заполнения пространства между записями текущим содержимым буфера файла. ·При чтении любых массивов, кроме являющихся элементами типов, определяемых пользователем, инструкция Get считывает только данные. Дескриптор не считывается. ·При считывании строк переменной длины, не являющихся элементами типов, определяемых пользователем, 2-байтовый дескриптор не считывается. Число считываемых байт равняется числу символов, уже содержащихся в строке. Например, следующие инструкции считают 10 байт из файла, которому соответствует номер 1: VarString = String(10," ") Get #1,,VarString Функция FileDateTime Возвращает значение типа Variant (Date), содержащее дату и время создания или последнего изменения файла. FileDateTime( путь) Обязательный аргумент путь является строковым выражением, указывающим имя файла. Аргумент путь может содержать имя каталога или папки и диска. Функция FileAttr Возвращает значение типа Long, представляющее режим файла для файлов, открытых с помощью инструкции Open. FileAttr(filenumber, returntype) filenumber - Обязательный. Значение типа Integer. Любой допустимый номер файла. returntype - Обязательный. Значение типа Integer. Число, указывающее характер возвращаемых данных. Значение 1 задает возвращение значения, указывающего режим файла. В 16-разрядных системах значение 2 задает возвращение дескриптора файла в операционной системе. В 32-разрядных системах значение 2 аргумента returntype не поддерживается и приводит к ошибке. Ниже приведено соответствие между режимами файла и значениями, возвращаемыми в том случае, если аргумент returntype имеет значение 1: Режим | Значение | Input | 1 | Output | 2 | Random | 4 | Append | 8 | Binary | 32 | Функция GetAttr Возвращает значение типа Integer, содержащее атрибуты файла, каталога или папки. GetAttr( путь) Обязательный аргумент путь является строковым выражением, указывающим имя файла. Аргумент путь может содержать имя каталога или папки и диска. Значение, возвращаемое функцией GetAttr, являются суммой следующих значений: Константа | Значение | Описание | vbNormal | 0 | Обычный. | vbReadOnly | 1 | Только чтение. | vbHidden | 2 | Скрытый. | vbSystem | 4 | Системный. | vbDirectory | 16 | Каталог или папка. | vbArchive | 32 | Файл был изменен после последнего резервирования. | Данные константы определяются в языке Visual Basic для приложений. Это означает, что их имена можно использовать в любом месте кода вместо фактических значений. Для определения установленных атрибутов следует с помощью оператора And выполнить поразрядное сравнение значения, возвращенного функцией GetAttr , и значения, соответствующего нужному атрибуту файла. Ненулевой результат означает, что данный атрибут установлен. Например, значение следующего выражения будет нулевым, если архивный атрибут не установлен: Result = GetAttr(FName) And vbArchive Если архивный атрибут установлен, будет возвращено ненулевое значение. Инструкция SetAttr Задает атрибуты файла. SetAttr pathname, attributes pathname - Обязательный. Строковое выражение, указывающее имя файла; может содержать имя каталога или папки и диска. attributes - Обязательный. Константа или числовое выражение, задающее атрибуты файла. Ниже приведены допустимые значения аргумента attributes: Константа | Значение | Описание | vbNormal | 0 | Обычный. | vbReadOnly | 1 | Только чтение. | vbHidden | 2 | Скрытый. | vbSystem | 4 | Системный. | vbDirectory | 16 | Каталог или папка. | vbArchive | 32 | Файл был изменен после последнего резервирования. | Данные константы определяются в языке Visual Basic для приложений. Это означает, что их имена можно использовать в любом месте кода вместо фактических значений. При попытке изменения атрибутов открытого файла возникает ошибка выполнения. Инструкция FileCopy Копирует файл. FileCopysource, destination source - Обязательный. Строковое выражение, указывающее имя файла, подлежащего копированию. Аргумент source может содержать имя каталога или папки и диска. destination - Обязательный. Строковое выражение, указывающее имя результирующего файла. Аргумент destination может содержать имя каталога или папки и диска. При попытке скопировать открытый файл с помощью инструкции FileCopy возникает ошибка. Инструкция Name Изменяет имя файла, каталога или папки. NameстароеИмяAsновоеИмя староеИмя - Обязательный. Строковое выражение, указывающее имя и положение существующего файла; может содержать имя каталога или папки и диска. новоеИмя - Обязательный. Строковое выражение, указывающее новое имя и положение файла; может содержать имя каталога или папки и диска. Файл с таким именем не должен существовать. Оба аргумента, новоеИмя и староеИмя, должны указывать на один и тот же диск. Если путь, указанный с помощью аргумента новоеИмя существует и отличен от указанного с помощью аргумента староеИмя, инструкция Name переместит файл в новый каталог или папку и переименует его (если требуется). Если пути, указанные с помощью аргументов новоеИмя и староеИмя, разные, а имена файлов совпадают, инструкция Name переместит файл в новый каталог или папку без изменения его имени. С помощью инструкции Name, можно переместить файл из одного каталога (или папки) в другой, однако нельзя переместить каталог или папку. При попытке переименовать открытый файл с помощью инструкции Name возникает ошибка. Прежде чем приступить к изменению имени файла, необходимо его закрыть. В аргументах инструкции Name не допускается использование подстановочных знаков для нескольких символов (*) и одного символа (?). Ну и теперь на основе вышеизложенного мы можем написать ряд весьма полезных процедур и функций. Создание текстового файла: Function FileUtils_CreateTextFile(strPath As String, Optional varBody As Variant) As String '© NSA Programmer, 2001. http://www.msaccess.ru ~ E- mail:
Этот e-mail защищен от спам-ботов. Для его просмотра в вашем браузере должна быть включена поддержка Java-script
~ ICQ: 7349882 '---------------------------------------------------------- ' Функция создает файл strPath и возвращает его имя в случае ' успешного создания, либо в случае, если такой файл уже есть. ' Если передан параметр varBody - его значение записывается в файл. '---------------------------------------------------------- On Error Resume Next Dim intFileNumber As Integer intFileNumber = FreeFile If Not FileUtils_IsFilePresent(strPath) Then Open strPath For Output As #intFileNumber If Err.Number = 0 Then FileUtils_CreateTextFile = strPath If (Not IsMissing(varBody)) Then Print #intFileNumber, varBody End If End If Else FileUtils_CreateTextFile = strPath End If Close #intFileNumber End Function | Запись в текстовый файл: Function FileUtils_PrintTextFile(strPath As String, Optional varBody As Variant = "", Optional blWriteToEnd As Boolean = True) As String '© NSA Programmer, 2001. http://www.msaccess.ru ~ E-mail:
Этот e-mail защищен от спам-ботов. Для его просмотра в вашем браузере должна быть включена поддержка Java-script
~ ICQ: 7349882 '---------------------------------------------------------- ' Записывает (Print) varBody в файл strPath и возвращает его имя в случае ' успешной записи. Если файла нет - создает его. ' Если передан параметр varBody - его значение записывается в файл. ' Если параметр varBody пропущен - в файл ничего не записывается. ' Если параметр blWriteToEnd = TRUE или пропущен - запись производиться ' в конец файла, если FALSE - в начало. '---------------------------------------------------------- On Error Resume Next Dim intFileNumber As Integer Dim tmpBody As Variant Dim tmp As Variant intFileNumber = FreeFile If Not FileUtils_IsFilePresent(strPath) Then If strPath <> FileUtils_CreateTextFile(strPath) Then Exit Function End If If blWriteToEnd = False Then Open strPath For Input As #intFileNumber Else Open strPath For Append As #intFileNumber End If If Err.Number = 0 Then FileUtils_PrintTextFile = strPath If Nz(varBody) <> "" Then If blWriteToEnd = False Then Do Until EOF(intFileNumber) Input #intFileNumber, tmp If Nz(tmp) <> "" Then tmpBody = tmpBody & vbCrLf & tmp End If Loop tmpBody = varBody & tmpBody Close #intFileNumber intFileNumber = FreeFile Open strPath For Output As #intFileNumber Print #intFileNumber, tmpBody Else Print #intFileNumber, varBody End If End If End If Close #intFileNumber End Function | Запись массива в текстовый файл: Function FileUtils_PrintTextFileInArr(strPath As String, ByRef arFile() As Variant, Optional blWriteToEnd As Boolean = True, Optional blLastToFirstArr As Boolean = False) As Boolean '© NSA Programmer, 2001. http://www.msaccess.ru ~ E- mail:
Этот e-mail защищен от спам-ботов. Для его просмотра в вашем браузере должна быть включена поддержка Java-script
~ ICQ: 7349882 '---------------------------------------------------------- ' Записывает (Print) построчно файл strPath из массива arFile. ' blWriteToEnd = TRUE - писать в конец файла ' blLastToFirstArr = TRUE - с конца до начала массива '---------------------------------------------------------- On Error Resume Next Dim i As Long Dim intStep As Integer Dim lngStart As Long Dim lngEnd As Long If blLastToFirstArr = False Then lngStart = 1 lngEnd = UBound(arFile) intStep = 1 Else lngStart = UBound(arFile) lngEnd = 1 intStep = -1 End If For i = lngStart To lngEnd Step intStep Call FileUtils_PrintTextFile(strPath, arFile(i), blWriteToEnd) Next i End Function | Чтение строк из текствого файла: Function FileUtils_ReadTextFile(strPath As String, Optional lngLine As Long = 0, Optional blReadToEnd As Boolean = False) As Variant '© NSA Programmer, 2001. http://www.msaccess.ru ~ E-mail:
Этот e-mail защищен от спам-ботов. Для его просмотра в вашем браузере должна быть включена поддержка Java-script
~ ICQ: 7349882 '---------------------------------------------------------- ' Считывает (Input) из файла strPath запись (строку) номер lngLine. ' Если передан параметр varBody - его значение записывается в файл. ' Если параметр lngLine пропущен - считывается весь файл. ' Если параметр blReadToEnd = TRUE или пропущен - чтение производиться ' с конца файла, если FALSE или пропущен - c начала. '---------------------------------------------------------- On Error Resume Next Dim intFileNumber As Integer Dim tmpBody As Variant Dim tmp As Variant Dim arTmp() As Variant Dim i As Long intFileNumber = FreeFile Open strPath For Input As #intFileNumber If Err.Number = 0 Then If blReadToEnd = True Or lngLine <= 0 Then Do Until EOF(intFileNumber) Input #intFileNumber, tmp If Nz(tmp) <> "" Then i = i + 1 ReDim Preserve arTmp(1 To i) arTmp(i) = tmp tmpBody = tmpBody & vbCrLf & tmp End If Loop tmpBody = Mid(tmpBody, 3) If blReadToEnd = True Then If lngLine > 0 Then If i - lngLine >= 0 Then FileUtils_ReadTextFile = arTmp(i - lngLine + 1) End If Else FileUtils_ReadTextFile = tmpBody End If Else If lngLine > 0 Then If i >= lngLine Then FileUtils_ReadTextFile = arTmp(lngLine) End If Else FileUtils_ReadTextFile = tmpBody End If End If Else Do Until EOF(intFileNumber) Input #intFileNumber, tmp If Nz(tmp) <> "" Then i = i + 1 If i = lngLine Then FileUtils_ReadTextFile = tmp Exit Do End If End If Loop End If End If Close #intFileNumber End Function | Чтение текстового файла в массив: Function FileUtils_ReadTextFileToArr(strPath As String, ByRef arFile() As Variant) As Boolean '© NSA Programmer, 2001. http://www.msaccess.ru ~ E-mail:
Этот e-mail защищен от спам-ботов. Для его просмотра в вашем браузере должна быть включена поддержка Java-script
~ ICQ: 7349882 '---------------------------------------------------------- ' Считывает (Input) построчно файл strPath в массив arFile. '---------------------------------------------------------- On Error Resume Next Dim intFileNumber As Integer Dim tmp As Variant Dim i As Long intFileNumber = FreeFile Open strPath For Input As #intFileNumber If Err.Number = 0 Then Do Until EOF(intFileNumber) Input #intFileNumber, tmp If Nz(tmp) <> "" Then i = i + 1 ReDim Preserve arFile(1 To i) arFile(i) = tmp End If Loop If Err.Number = 0 Then FileUtils_ReadTextFileToArr = True End If Close #intFileNumber '---------------------------------------------------------- 'Возможный вызов функции: '... 'Dim d() As Variant 'Call FileUtils_ReadTextFileToArr("E:1.txt", d()) '... '---------------------------------------------------------- End Function | Форматированная запись одномерного массива в текстовый файл: Function FileUtils_WriteTextFile(strPath As String, ByRef arFile() As Variant, Optional blWriteToEnd As Boolean = True) As String '© NSA Programmer, 2001. http://www.msaccess.ru ~ E-mail:
Этот e-mail защищен от спам-ботов. Для его просмотра в вашем браузере должна быть включена поддержка Java-script
~ ICQ: 7349882 '---------------------------------------------------------- ' Записывает (Write) одномерный массив arFile в файл strPath и возвращает его имя в случае ' успешной записи. Если файла нет - создает его. ' Если параметр blWriteToEnd = TRUE или пропущен - запись производиться ' в конец файла, если FALSE - в начало. '---------------------------------------------------------- On Error Resume Next Dim intFileNumber As Integer Dim tmpBody() As Variant Dim tmp As Variant Dim lngBound As Long Dim lngBoundTmp As Long Dim i As Long Dim j As Long intFileNumber = FreeFile If Not FileUtils_IsFilePresent(strPath) Then If strPath <> FileUtils_CreateTextFile(strPath) Then Exit Function End If If blWriteToEnd = False Then Open strPath For Input As #intFileNumber Else Open strPath For Append As #intFileNumber End If If Err.Number = 0 Then lngBound = UBound(arFile) If blWriteToEnd = False Then i = -1 Do Until EOF(intFileNumber) i = i + 1 Input #intFileNumber, tmp ReDim Preserve tmpBody(0 To i) tmpBody(i) = tmp Loop lngBoundTmp = i + 1 Close #intFileNumber intFileNumber = FreeFile Open strPath For Output As #intFileNumber For i = 0 To lngBound - 1 Write #intFileNumber, arFile(i); Next i Write #intFileNumber, arFile(i) For i = 0 To (lngBoundTmp) / (lngBound + 1) - 1 For j = 0 To lngBound - 1 Write #intFileNumber, tmpBody(j + (i * (lngBound + 1))); Next j Write #intFileNumber, tmpBody(j + (i * (lngBound + 1))) Next i Else For i = 0 To lngBound - 1 Write #intFileNumber, arFile(i); Next i Write #intFileNumber, arFile(i) End If End If Close #intFileNumber End Function | Форматированная запись двухмерного массива в текстовый файл: Function FileUtils_WriteTextFileInArr(strPath As String, ByRef arFile As Variant, Optional blWriteToEnd As Boolean = True, Optional blLastToFirstArr As Boolean = False) As Boolean '© NSA Programmer, 2001. http://www.msaccess.ru ~ E- mail:
Этот e-mail защищен от спам-ботов. Для его просмотра в вашем браузере должна быть включена поддержка Java-script
~ ICQ: 7349882 '---------------------------------------------------------- ' Записывает (Write) файл strPath из двухмерного массива arFile. ' blWriteToEnd = TRUE - писать в конец файла ' blLastToFirstArr = TRUE - с конца до начала массива '---------------------------------------------------------- On Error Resume Next Dim i As Long Dim j As Long Dim arTmp() As Variant Dim intStep As Integer Dim lngStart As Long Dim lngEnd As Long If blLastToFirstArr = False Then lngStart = 0 lngEnd = UBound(arFile, 2) intStep = 1 Else lngStart = UBound(arFile, 2) lngEnd = 0 intStep = -1 End If ReDim arTmp(UBound(arFile, 1)) For i = lngStart To lngEnd Step intStep For j = 0 To UBound(arFile, 1) arTmp(j) = arFile(j, i) Next j Call FileUtils_WriteTextFile(strPath, arTmp(), blWriteToEnd) Next i End Function | Форматированная запись рекордсета в текстовый файл: Function FileUtils_WriteTextFileInRecordset(strPath As String, ByRef rst As Recordset, Optional blWriteToEnd As Boolean = True, Optional blLastToFirstArr As Boolean = False) As Boolean '© NSA Programmer, 2001. http://www.msaccess.ru ~ E- mail:
Этот e-mail защищен от спам-ботов. Для его просмотра в вашем браузере должна быть включена поддержка Java-script
~ ICQ: 7349882 '---------------------------------------------------------- ' Записывает (Write) набор записей rst в файл strPath '---------------------------------------------------------- Dim arTmp As Variant If rst.RecordCount <> 0 Then rst.MoveLast rst.MoveFirst arTmp = rst.GetRows(rst.RecordCount) Call FileUtils_WriteTextFileInArr(strPath, arTmp, blWriteToEnd, blLastToFirstArr) End If End Function | Форматированное чтение текствого файла в двухмерный массив: Function FileUtils_InputTextFileToArr(strPath As String, ByRef arFile As Variant) As Boolean '© NSA Programmer, 2001. http://www.msaccess.ru ~ E-mail:
Этот e-mail защищен от спам-ботов. Для его просмотра в вашем браузере должна быть включена поддержка Java-script
~ ICQ: 7349882 '---------------------------------------------------------- ' Считывает (Input) файл strPath в двухмерный массив arFile. '---------------------------------------------------------- On Error Resume Next Dim intFileNumber As Integer Dim tmp As Variant Dim i As Long Dim j As Long Dim lngFldCnt As Long lngFldCnt = UBound(arFile, 1) + 1 i = -1 intFileNumber = FreeFile Open strPath For Input As #intFileNumber If Err.Number = 0 Then Do Until EOF(intFileNumber) Input #intFileNumber, tmp i = i + 1 If i lngFldCnt = i / lngFldCntThen ReDim PreservearFile(lngFldCnt - 1, (i lngFldCnt)) End If arFile(i - lngFldCnt * (i lngFldCnt), (i lngFldCnt)) = tmp Loop If Err.Number = 0 ThenFileUtils_InputTextFileToArr = True End If Close #intFileNumber End Function | Много, много полезных функций можно ещенаписать... Но для урока -достаточно. Возможно сюда ещебудут добавляться функции... Просмотров: 12997
 Ваш коментарий будет первым | | |