Страницы: 1 2 След.
RSS
Автоматический перенос информации из тела письма outlook в Excel
 
По роду деятельности получаю много однообразных писем, в едином формате, из которых информацию переношу вручную а таблицу excel для анализа. Можно ли как-то автоматизировать этот процесс? Те есть можно ли написать какой- либо макрос для outlook который бы выполнялся по открытию письма, оттуда брались данные и переносились в таблицу.
Черным подчеркнуты слова, которые должны быть заголовками колонок в таблице, и туда должны импортироваться данные после двоеточия. Также дан пример
таблицы.
Заранее благодарен за помощь

 
Такой макрос сделать можно. Как вариант открываем инспектор письма (т.е. двойной щелчок ЛКМ на сообщении) и потом, например, альт + 1 будет вызывать макрос, который будет открывать нужную книгу и заносить эти данные в книгу. Макрос простой.
С уважением,
Федор/Все_просто
 
к сожалению не владею этим навыком, можем сможете написать?
 
Делать отладку в Outlook для меня лично сложнее, чем в Excel. "Для себя" я бы сделал гораздо быстрее, потому что были бы "живые" входные данные. Здесь же кроме скрина ничего нет  :(  
Готовьтесь к серии постов.

upd Скопируйте пару примеров писем, чтобы легче было написать парсер для письма.

upd2 Ну что ж. Ответа не последовало. Задание делать не буду. Удачи.
Изменено: Все_просто - 19.01.2015 22:13:16
С уважением,
Федор/Все_просто
 
Все_просто, день добрый! Тема на самом деле очень актуальная.
Могу привести свой пример постановки задачи.
Ниже примеры текста писем из системы мониторинга:
1.
При трассировке пользователем Петров Иван Иванович в 20.01.2015 15:50:00 получены результаты:
Передача тестового объема данных по направлениям:
сервер - клиент: 765 мс
клиент - сервер: 780 мс
тестовый объем: 2 048 Кб
2.
При трассировке пользователем Иванова Елена Леонидовна в 13.01.2015 12:41:37 получены результаты:
Передача тестового объема данных по направлениям:
сервер - клиент: 1 513 мс
клиент - сервер: 2 290 мс
тестовый объем: 2 048 Кб

Тема всех писем: Результаты трассировки
Нужно, чтобы данные из писем разбирались в табличку Excel
Email всегда одинаковый. Хотелось бы еще выводить в таблицу дату и время получения письма на email.

Как можно решить проблему?
 
Лучше попробовать договориться с отправителем писем, что бы данные генерировали например в csv.
А уже на событие получения письма анализировать отправителя и загружать данные. Да и вообще для таких обменов идеально FTP подходит.
 
Если будете отвечать на мои посты в этой теме, попробую сделать и сделаю (если получится) совершенно бесплатно. :)
С уважением,
Федор/Все_просто
 
B.Key , идея хорошая, но в том то и дело, что на входе есть только письма. Договориться с отправителем проблематично..
Все_просто, буду стараться, правда инициатор темы был изначально не я. Думаю, многим в сообществе пригодилось бы решение вопроса!  ;)
 
kot_ik, Посмотри на SQL   подстрой (доделай) под свою задачу
 
Похоже, что изобретаю велосипед. Хоть и написано уже больше 100 строчек кода, перестану писать, если ссылка B.Key работает. Если работает, могу выложить то, что уже написал.
С уважением,
Федор/Все_просто
 
B.Key, спасибо, посмотрел ссылку, правда, для моих неглубоких познаний, это слишком общий вариант. Там задача сводится к присвоению определенного значения ячейке книги MS Excell, а мне нужен разбор содержания письма по столбцам. Еще не понял где создается книга Excel, т.к. путь к ней в примере не указан. Самостоятельно доделать этот пример мне трудно :(

Все_просто, давайте продолжим также и ваш вариант решения. Велосипед велосипеду рознь))
 
Решил для себя данную задачу "взад", и с помощью access (А2010).
Не в outlook смотрю, а сразу в акцессе
Дело в том, что в А2010 есть встроенная возможность цепляться и выгружать в таблицы данные из outlook.
Потом, прямо в акцессе, из этой таблицы можно удалять сообщения, и они сразу удаляются и в outlook.
В новой базе данных нужно сделать так:Вкладка Внешние данные - Дополнительно - Папка Outlook.
А там уже можно например перекидывать нужные записи в отдельную таблицу.
А ексель уже при желании может забирать из базы акцесса данные например с помощью MS Query (встроенная штучка екселя, находится во вкладке Данные-Получение внешних данных-Из других источников-Из Microsoft Guery...
Изменено: Михаил Лебедев - 21.01.2015 11:27:02
Всё сложное - не нужно. Всё нужное - просто /М. Т. Калашников/
 
Тогда продолжаем. Могу выкладывать код частями, по мере готовности/окончания отлаживания(тестирования), а могу все сразу.
Постараюсь до конца дня дать первые результаты. На данный момент есть парсер сообщений, процедура, открывающая книгу. Сейчас отлаживаю вставку данных в книгу и закрытие книги. Остается построить логику отбора сообщений.
С уважением,
Федор/Все_просто
 
Михаил Лебедев, идея-то хорошая. Да вот не всегда она осуществима. Первое, самое важное, не у всех есть аксес. Второе, это надо отлаживать сразу 3 приложения (в моем понимании). Ну а в-третьих, с объектной модель access'а я не работал. Примерно понимаю, какие нужны references, но вдаваться в подробности не хочется. Спасибо за идею.
С уважением,
Федор/Все_просто
 
Набросал вам логику оутлука, нет времени парсить текст( лучше использовать regexp, так как нет нужного образца не делал)

вставить в модуль оутлука thisoutlooksession
Код
Private Sub Application_NewMail()
    Set myOlApp = Application
    Set myNameSpace = myOlApp.GetNamespace("MAPI")
    Set myFolder = myNameSpace.GetDefaultFolder(olFolderInbox)
    Set myitem = myFolder.Items(myFolder.Items.Count)
   
    If myitem.SenderName = "Нужный отправитель" Then 
 txt = myitem.Body
     a = Split(txt, vbNewLine)
    For i = 0 To UBound(a)
   
        If InStr(1, a(i), "При трассировке пользователем") > 0 Then Stop: us = "FIO" ' тут необходимо распарсить нужный текст
        If InStr(1, a(i), "сервер - клиент:") > 0 Then Stop: Ls = 123 ' тут необходимо распарсить нужный текст
        If InStr(1, a(i), "клиент - сервер: ") > 0 Then Stop: UpLs = 123 ' тут необходимо распарсить нужный текст
        If InStr(1, a(i), "тестовый объем: ") > 0 Then: dSize = 1234 ' тут необходимо распарсить нужный текст
    Next
Set XL = CreateObject("excel.application")
XL.Visible = False
xlsFileName = "C:\test.xls" 'Путь к вашему файлу
Set b = XL.workbooks.Open(xlsFileName)
Set r = b.Application.Range("DATA") 'имя вашей таблицы
i = r.rows.Count
r(i + 1, 1) = us
r(i + 1, 2) = Ls
r(i + 1, 3) = UpLs
r(i + 1, 4) = dSize
b.Close True
XL.Quit
End If
End Sub
 
Изменено: B.Key - 21.01.2015 12:44:20
 
B.Key, вопрос в чисто ознакомительных целях. Может быть логичней было бы:
Код
     txt = myitem.Body
    a = Split(txt, vbNewLine)
поставить после:
Код
    If myitem.SenderName = "Нужный отправитель" Then
И ещё вопрос по строке:
Код
Set b = a.workbooks.Open(xlsFileName)
Ранее использовалась "a", как массив, а тут как объект. Не ошибка ли тут? Заранее прошу прощения, если что.

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
Если все же нужно, допишу.
Ну вот, пока думал - уже написали.  :(  
Выложу тогда парсер. Вот он:

Код
Function ExtractFromMail(mi As MailItem, dicKeys, Optional sep = vbNewLine)
    Dim key, val
    Dim StartPos&, EndPos&
    
    Dim txtBody: txtBody = mi.Body
    Dim Dic: Set Dic = CreateObject("Scripting.Dictionary")
    
    On Error Resume Next
    
    For Each key In dicKeys
        val = Split(txtBody, key)(1)
        val = Split(val, sep)(0)
        val = Replace(val, ": ", "")
        Dic.Add key, val
    Next key
    Dic.Add "Пользователь", mi.SenderName
    Dic.Add "Дата/время", mi.ReceivedTime
    
    On Error GoTo 0
    
    Set ExtractFromMail= Dic 
End Function 
где dicKeys =
Код
Split("сервер - клиент:клиент - сервер:тестовый объем", ":")
Изменено: Все_просто - 21.01.2015 12:24:06
С уважением,
Федор/Все_просто
 
Да все верно, ошибки исправил :))) не отлаживал
 
да и тут берется самое последнее письмо из папки входящие, оутлоок можно настроить что бы письма от определенного адресата попадали сразу в любую папку(созданную пользователем), затем анализировать эту папку.
 
Цитата
B.Key пишет: оутлоок можно настроить что бы письма от определенного адресата попадали сразу в любую папку(созданную пользователем), затем анализировать эту папку.
Необязательно настраивать таким образом, хотя и удобнее. Чтобы сделать макрос универсальнее можно воспользоваться методом restrict коллекции Items, который отфильтрует не только имя получателя, но и статус прочтения. Эквивалентом в интерфейсе outlook является (ктрл + у).
Изменено: Все_просто - 21.01.2015 12:33:09
С уважением,
Федор/Все_просто
 
Попробовал совет Михаила Лебедева - Access зависает и закрывается в процессе импорта. Неудобно будет работать в трех приложениях. К тому же в аксессе дополнительно придется фильтровать список перед обменом с эксель.

Все_просто, хорошо будет, если допишете. Если это не очень обременительно для вас.
 
B.Key, а этот вариант будет работать, если письма приходят не в личную папку входящих, а в общую папку Outlook ? И еще - под именем таблицы имеется ввиду название листа?
 
Код
 Option Explicit
Dim wb As Object
Dim Wsh As Object
Dim App As Object
Dim blnEnd As Boolean
Dim rng As Object
Dim arr As Object
Dim filteredItems As items

Sub OpenBook(path As String, fileName As String)
    Dim fname As String

    Set App = CreateObject("Excel.Application")
    Dim fullPath As String: fullPath = path & App.PathSeparator & fileName
    If Dir(fullPath) <> "" Then
        Set wb = App.Workbooks.Open(fullPath)
        App.Visible = True
        wb.Activate
    Else:
        Select Case MsgBox("Создать новую книгу?", vbYesNo)
        Case vbYes: Set wb = App.Workbooks.Add
        Case vbNo: blnEnd = True
        End Select
        If Not blnEnd Then
            Do
                fname = App.GetSaveAsFilename & ".xls"
            Loop Until fname <> ""
            wb.SaveAs fileName:=fname
            App.Visible = True
            wb.Activate
        End If
    End If
End Sub
Sub ManageWB(ParamArray ColNames())
    Set Wsh = wb.Worksheets(1)
    Set rng = Range("A1").CurrentRegion
    If rng.Cells.Count = 1 Then
        rng.Resize(1, UBound(ColNames) + 1).Value = ColNames
    End If
    Set rng = rng(1, 1)

    Dim name
    Dim i&
    Dim lastRow&: lastRow = rng.CurrentRegion.Rows.Count

    Call getCollectionOfMails("Ваше_условие")
    Dim mi As MailItem
    Dim vals
    vals = Split("сервер - клиент:клиент - сервер:тестовый объем", ":") 
    On Error Resume Next

    For Each mi In filteredItems

        Set arr = ExtractFromMail(mi, vals)
        Select Case lastRow

        Case Is < 2
            For Each name In ColNames
                i = i + 1
                rng.Find(name).Offset(1, 0).Value = arr(name)
                If Err.Number <> 0 Then
                    MsgBox "There is an error in function"
                    Exit Sub
                End If
            Next name

        Case Is >= 2
            For Each name In ColNames
                If arr.Exists(name) Then
                    rng.Parent.Cells(lastRow + 1, rng.Find(name).Column) = arr(name)
                End If
            Next name

        End Select  

       Next mi
        On Error GoTo 0
        wb.Close SaveChanges:=True
        App.Quit
End Sub
Function ExtractFromMail(mi As MailItem, dicKeys, Optional sep = vbNewLine)
    Dim key, val
    Dim StartPos&, EndPos&

    Dim txtBody: txtBody = mi.Body
    Dim Dic: Set Dic = CreateObject("Scripting.Dictionary")

    On Error Resume Next

    For Each key In dicKeys
        val = Split(txtBody, key)(1)
        val = Split(val, sep)(0)
        val = Replace(val, ": ", "")
        Dic.Add key, val
    Next key
    Dic.Add "Пользователь", mi.SenderName
    Dic.Add "Дата/время", mi.ReceivedTime

    On Error GoTo 0

    Set ExtractFromMail = Dic
End Function
Sub getCollectionOfMails(condition As String, Optional blnUnRead As Boolean = False)
    Dim fld As Folder: Set fld = Session.Folders(2).Folders("Входящие") ' это мой адрес входящей папки - придется изменить
    Dim i As items: Set i = fld.items

    Dim fullCondition As String

    fullCondition = "[От] = '" & condition & "'"
    Set filteredItems = i.Restrict(fullCondition)
End Sub
Sub setNothing()
    Set wb = Nothing
    Set Wsh = Nothing
    Set App = Nothing
    Set rng = Nothing
    Set arr = Nothing
    Set filteredItems = Nothing
End Sub
Sub main()
    Dim p As String: p = "C:\Ex"    'path
    Dim fn As String: fn = "Трассировка.xlsx"
    Call OpenBook(p, fn)
    If blnEnd Then
        MsgBox "Something wasn't right", vbCritical, "Oooops!"
        Exit Sub
    End If
    Call ManageWB("Пользователь", "сервер - клиент", "клиент - сервер", _
                  "тестовый объем", "Дата/время")
    Call setNothing
End Sub
 
Надо будет еще дорабатывать. Кириллица криво вставилась, поэтому не обессудьте, если что не так в условиях, содержащие кириллицу.
Изменено: Все_просто - 21.01.2015 13:06:25
С уважением,
Федор/Все_просто
 
Разбираю свой код.
1.Основная процедура - sub main(). Ее и вызываем, чтобы получить книгу с записями.
2.Процедура OpenBook. Есть два аргумента: путь к папке и название искомого файла с расширением.После вызова процедуры на глобальном уровне устанавливается объект книга - книга над которой будет в будущем проводиться операция вставки данных. Если аргументы даны не верно, вызывается диалоговое окно, в котором можно указать путь к нужной папке. В названии файла указываем собственно название без расширения. Расширение добавляется автоматически (xls). В итоге добавляется, а потом и сохраняется книга с именем, которое мы дали используя диалоговое окно.
3.Процедура GetCollectionOfMails. В процедуре есть один аргумент-условие отбора. Вызов процедуры генерирует на глобальном уровне коллекцию писем, которые отфильтрованы по имени отправителя (далее этот аргумент будет использоваться для вставки в ячейку книги "Трассировка". В другой процедуре (будет описана дальше) используется цикл, который перебирает пописьменно (то есть поочередно письмо за письмом) данную отфильтрованную коллекцию.
4.Функция-парсер ExtractFromMail. Возвращает объект словарь (dictionary). Для каждого ключа (содержится в массиве dicKeys - одного из аргументов функции) парсится нужное значение. Другими аргументами функции являются mi - парсящее сообщение, а также sep - разделитель, благодаря которому отделяются значения собственно нужные значения для вставки в книгу. По умолчанию sep = перенос. Если сообщение не парсится, то в этой функции, которая содержится в процедуре под 5 номером, необходимо поменять этот критерий. В словаре, возвращаемом парсером, также добавлены ключи "Пользователь" - имя отправителя письма (владельца e-mail), а также время получения письма/
=================
Небольшое отступление: макрос еще нужно дорабатывать и оптимизировать. Например в 4 пункте следовало бы вставить константу в опциональную часть, чтобы не мучиться с поиском описанным в пункте 4. Недостаток приведенного также в том, что некоторые аргументы повторяются. И их было бы неплохо выложить/инстанциировать на глобальном уровне, а так и дальше будут пользоваться ненужные массивы, которые декларируются через paramarray, например.
=================
5.Рабочей лошадкой сего действия выступает процедура ManageWB. К сожалению, я ее не отлаживал, поэтому почти наверняка там будут ошибки. Почему не отлаживал - потому что огорчился, от того, что кто-то уже выложил решение, причем вроде-как неплохое. В процедуре один аргумент - paramarray, в который записываются все названия колонок в книге. Данная процедура проверяет открывшуюся книгу. Если в ней только одна строка - то на следующей вставляются данные. Если книга уже была создана и в ней есть данные, данные будут вставляться после последней вставленной строки. Желательно, чтобы все строки вставлялись полностью (т.е., чтобы не было дыр из пустых значений - "" ) . После вех операций книга закрывается с сохранением, а также мы выходим из приложения Excel.
6.Процедура SetNothing. Все глобальные переменные "обнуляются".

В моем понимании, макрос можно доработать, чтобы он работал без References.
Изменено: Все_просто - 21.01.2015 14:34:30
С уважением,
Федор/Все_просто
 
Все_просто, спасибо за разъяснения по коду. Можете еще рассказать как применить макрос. Просто вставить его в исходный текст листа в файле для парсинга? В начале темы было предложение от вас вызывать макрос по альт + 1 через инспектор письма. Это было бы удобно. Как в итоге это работает?
 
kot_ik, макрос еще надо будет отшлифовать и доработать. Если хочется через инспектор письма, то нужно будет немного переделать. Так как каркас макроса уже написан дальше нужно будет просто заниматься всесторонней отладкой. Сейчас пока нет времени этим заниматься. Но что начал, я постараюсь закончить.

upd. Забыл написать про то, как применять. Надо вставить данный код в модуль проекта в Outlook. Для этого заходим в Outlook, нажимаем Alt+F11. Вставляем модуль, а потом и код. Применение я уже написал постом выше, почитайте, для Ваших нужд надо будет еще настраивать.
Изменено: Все_просто - 22.01.2015 11:12:07
С уважением,
Федор/Все_просто
 
Кодировка VBA гиблое место. Еле вставил, к сожалению с потерей отступов. Если в коде будет ошибка - то это ошибка по причине кодировки. Если кому нужно вышлю на почту/выложу в файлообменник bas-файл.
А теперь пояснения. Работает без вставки связей (references). Чтобы макрос сработал открываем инспектор письма и запускаем процедуру main. Вот и все. Протестировано на MS Office 2010 x86.
Теперь по настройкам. При активном Outlook'e нажимаем alt + F11, далее поочередно (заранее переключившись на латиницу) alt → i → m. В появившемся модуле сохраняем приведенный макрос.
В самом верху макроса нужно будет поменять 2-3 константы (начинается на Const):
*separator - то чем отделяется строка в парсируемом сообщении (скорее всего менять не нужно будет)
*wbkAddress - адрес папки, в которой находится файл для вставки значений
*fileName - название файла с расширением.
Файл должен соответствовать приведенному шаблону. Это касается как таблицы (адрес колонок), так и листа (все операции по вставки проводятся на первом по счету листе).
Чтобы воспользоваться горячими клавишами alt + цифра, делаем вот что:
Открываем инспектор письма (для 2010, возможно и для 2013), настройка панели быстрого доступа, Выбрать команды из → выбираем макросы, далее выбираем процедуру main. Похоже, что все.
Ах да, про возможные ошибки при выполнении. Если инспектор сообщения не открыт - выдаст удобочитаемую ошибку, если сообщение не парсится - выдаст ту же ошибку. По завершении макрос извести об успешном завершении операции вставки. Возможно надо будет доработать макрос в том смысле, что могут возникнуть проблемы, если файл уже открыт. В таком случае нужно будет вставить несколько строк, которые содержат функцию Dir, но это уже совсем другая история.  :)  
Код
'---------------------------------------------------------------------------------------
' Module      : Final
' Author      : Fjedor/Vse_Pro100 @ PlanetaExcel.ru
' Date        : 23.01.2015
' Purpose     : moves parsed data into excel workbook.
' Miscelaneous: Please, make sure the code is properly attributed when used.
'---------------------------------------------------------------------------------------

Option Explicit
Const keys As String = _
   "сервер - клиент:клиент - сервер:тестовый объем" ':Пользователь:Дата/время"
Const separator As String = vbNewLine
Const wbkAddress = "C:\book\"
Const fileName = "Test.xlsx"
Const userPattern = "\.*пользователем\s(\.*)\s*в\s*(\d+.\d+.\d+\s\d+:\d+:\d+).*"

Enum ColNames
U = 1 'user
SC = 2 'server-client
CS = 3 'client-server
TV = 4 'test volume
dt = 5 'date/time
End Enum


Function ExtractFromMail(mi As MailItem, Optional sep = vbNewLine)

Dim key, val
Dim StartPos&, EndPos&
Dim txtBody: txtBody = mi.Body
Dim dic As Object: Set dic = CreateObject("Scripting.Dictionary")
Dim user$, dt$

With CreateObject("vbscript.regexp")
.Pattern = userPattern
With .Execute(txtBody)(0)
user = .SubMatches(0)
dt = .SubMatches(1)
End With
End With

On Error Resume Next

For Each key In Split(keys, ":")
val = Split(txtBody, key)(1)
val = Split(val, separator)(0)
val = Replace(val, ": ", "")
dic.Add key, val
Next key

dic.Add "Пользователь", user
dic.Add "Дата/время", dt

On Error GoTo 0

Set ExtractFromMail = dic
End Function
Sub main()

Dim xl As Object: Set xl = CreateObject("Excel.Application") ': xl.Visible = False ': Set xl = New Excel.Application:
Dim wbk As Object: Set wbk = xl.Workbooks.Open(wbkAddress & fileName)
Dim rng As Object: Set rng = wbk.Worksheets(1).[a2].CurrentRegion
Dim lastRow&: lastRow = rng.Rows.Count
Dim mi As MailItem
Dim i&

On Error Resume Next

Set mi = ActiveInspector.CurrentItem
Dim dic As Object: Set dic = ExtractFromMail(mi)

With rng.Parent
.Cells(lastRow + 1, ColNames.U) = dic("Пользователь")
.Cells(lastRow + 1, ColNames.SC) = dic("сервер - клиент")
.Cells(lastRow + 1, ColNames.CS) = dic("клиент - сервер")
.Cells(lastRow + 1, ColNames.TV) = dic("тестовый объем")
.Cells(lastRow + 1, ColNames.dt) = dic("Дата/время")
End With

On Error GoTo 0
If Err.Number <> 0 Or dic Is Nothing Then
Dim str As String
str = "Инспектор для сообщения не вызван либо сообщение не валидно"
MsgBox str, vbCritical, "Ошибка"
wbk.Close SaveChanges:=False
GoTo Handler
End If

wbk.Close SaveChanges:=True
MsgBox "Записи успешно занесены", vbInformation

Handler:
xl.Quit
Set xl = Nothing: Set wbk = Nothing: Set dic = Nothing
End Sub
Изменено: Все_просто - 23.01.2015 02:24:52
С уважением,
Федор/Все_просто
 
Добрый день, Все просто! Попробовал в открытом письме запустить макрос - ничего не происходит. Приложил скриншоты макроса и письма, в котором выведен быстрый запуск Проекта main. В чем может быть проблема?
Изменено: kot_ik - 23.01.2015 09:42:36
 
Мне сложно сказать, в чем проблема. Main похоже правильно выведен. Но он никак не должен влиять на работу макроса. Я протестировал, отправив на свою почту похожее сообщение. Перепроверьте названия папок и файлов, которые задаются в самом верху кода.
Повторюсь: у меня в 2010 офисе все получилось.
С уважением,
Федор/Все_просто
 
Цитата
kot_ik пишет:
Попробовал совет Михаила Лебедева - Access зависает и закрывается в процессе импорта. Неудобно будет работать в трех приложениях. К тому же в аксессе дополнительно придется фильтровать список перед обменом с эксель.
Действительно, если подцепляться напрямую к папке Входящие - акцесс ругается. Но не виснет. Если же цепляться к созданной папке оутлук, в которую по созданныйм в нем правилам будут падать письма нужные - всё работает.

А MS Query - там всё совсем просто. Это интерфейс для создания в екселе запроса на базу акцесс (или файл ексель, например). После создания запроса данные напрямую при открытии файла (или периодически) с базы падают (обновляются) в ексель
Изменено: Михаил Лебедев - 23.01.2015 12:17:11
Всё сложное - не нужно. Всё нужное - просто /М. Т. Калашников/
 
Попробуйте сделать импорт модуля, а потом поменять настройки, как я объяснял.
Вот ссылка: http://dropmefiles.com/UdNTe
Изменено: Все_просто - 23.01.2015 13:24:13
С уважением,
Федор/Все_просто
Страницы: 1 2 След.
Наверх