Rambler's Top100
Форум: MS ACCESSVBVBA MS OfficeMS SQL server
Новые сообщения: 0000

Форум: MS ACCESS

Вопросы связанные с MS ACCESS

Обновить визитку
Участники «Online»
Все участники

 
 

Доброго времени суток, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Сканирование ворда
 
 автор: час   (02.07.2012 в 23:33)   личное сообщение
 
 

где бы глянуть как по вордовскому документу по строкам лазить и искать нужные и считывать инфу?

  Ответить  
 
 автор: Йожык   (03.07.2012 в 00:23)   личное сообщение
 
 

Часом, не банковскую ли выписку порастырить?

  Ответить  
 
 автор: час   (03.07.2012 в 10:07)   личное сообщение
 
 


где то тут позднее связывание валялося.
вроде бы оно!
http://hiprog.com/index.php?option=com_content&task=view&id=371
но не совсем... мне не шаблон надо открыть, а конкретный документ.

  Ответить  
 
 автор: час   (03.07.2012 в 10:25)   личное сообщение
 
 

Кто знает как по строчкам Ворда бегать? кидая их в переменную и вычленять нужный кусок?
Есть у кто нибудь код такой?

  Ответить  
 
 автор: kot_k_k   (03.07.2012 в 10:43)   личное сообщение
 
 

а там эсть rtf и doc файлы - и они разные.

  Ответить  
 
 автор: час   (03.07.2012 в 10:50)   личное сообщение
 
 

мне для xxx.doc

  Ответить  
 
 автор: Дядя Федор   (03.07.2012 в 11:08)   личное сообщение
 
 

Глянь http://www.askit.ru/custom/vba_office/m10/10_04_01_word_documents_collection.htm

там есть свойства content, characters и т.п.

У меня где-то было, но дома.

  Ответить  
 
 автор: час   (03.07.2012 в 11:15)   личное сообщение
 
 

спасибо.
Всё очень подробно и доходчиво описано.
Мож я не пральна задачу описал?

мне нуна поздне связывание с вордом и считывание построчно документа.

есть у кто нибудь кусок кода?

  Ответить  
 
 автор: Дядя Федор   (03.07.2012 в 11:17)   личное сообщение
 
 

А что надо - не менять случаем найденное на что-то?
Такая приблуда есть у меня.
Или мы не знаем что там?

  Ответить  
 
 автор: час   (03.07.2012 в 11:35)   личное сообщение
 
 

ничё не менять.
построчно считывать строки в переменную
и всё.

  Ответить  
 
 автор: час   (03.07.2012 в 11:37)   личное сообщение
 
 

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

Dim notepadID 
Private Sub Command1_Click() 
'Чтение первого файла 1.DOC 
Set appWrd = CreateObject("Word.Application") 
   'appWrd.Visible = True 
    Set oDoc1 = appWrd.Documents.open("c:\1.doc") 
    Set Param = oDoc1.Content.Paragraphs 
  notepadID = Shell("NOTEPAD.EXE " & "c:\txt", 1) ' Открытие Notepad. 
'Построчное чтение строк из первого файла 
    With oDoc1 
      .Parent.Visible = True 
       For I = 1 To 100 
       On Error GoTo m1 
       Param = .Paragraphs(I) 
         AppActivate notepadID 
SendKeys "^" & Param, True 'Посылка строки в Notepad. 
       Next 
   End With 
m1: 
oDoc1.Close 
appWrd.Quit 
'notepadID.Quit 
End Sub 


но тут похоже целыми параграфами читает..
а мне то построчно нуна....

  Ответить  
 
 автор: Дядя Федор   (03.07.2012 в 11:56)   личное сообщение
 
 

на вскидку - oDoc1.characters не пробовал?

Set Param = oDoc1.Content => Param - весь контент. далее анализировать по переводу строк

  Ответить  
 
 автор: час   (03.07.2012 в 11:59)   личное сообщение
 
 

пока ничё не пробовал, ищу код похожий, что бы пробовать.
что то нигде в инете не попадается, может запрос поиска не так пишу?

  Ответить  
 
 автор: Дядя Федор   (03.07.2012 в 12:04)   личное сообщение
 
 

Set Param = oDoc1.Content '.Paragraphs
Debug.Print "" & Param


=====================
окно отладки
=====================
Проверка текста трататата
И чето там еще

  Ответить  
 
 автор: час   (03.07.2012 в 12:12)   личное сообщение
 
 

угу

  Ответить  
 
 автор: Дядя Федор   (03.07.2012 в 12:17)   личное сообщение
 
 

И делай с ним что хош!

Public Sub ttt()
Dim varmas
'Чтение первого файла 1.DOC
Set appWrd = CreateObject("Word.Application")
   'appWrd.Visible = True
    Set oDoc1 = appWrd.Documents.Open("c:\test.doc")
    Set param = oDoc1.Content '.Paragraphs
    Debug.Print "" & param
    'Построчно в массив
    varmas = Split(param, Chr(13))

m1:
oDoc1.Close
appWrd.Quit
End Sub


забавно если есть таблицы...

  Ответить  
 
 автор: час   (03.07.2012 в 12:23)   личное сообщение
 
 

Спасибо, попробываю!
Чё та не то
цикла по строкам то нету.
Считываем сразу всё...

  Ответить  
 
 автор: Дядя Федор   (03.07.2012 в 12:28)   личное сообщение
 
 

Так считалась таблица из двух столбцов, в которых цифры 1 и 2

1
квадратик2
квадратик
квадратик



  Ответить  
 
 автор: час   (03.07.2012 в 13:25)   личное сообщение
 
 

мне нуна найти строку, подходящую по критерию отбора
затем эту строку расделить на две подстроки
а сама строка имеет вид

"Название продукта его характеристика "
=======================================
до того, как пойдут нужные строки ещё куча ненужного текста.
Потому мне нуна построчно считывать и аннннналлллизировать - что это за строка.
нуно построчно.

  Ответить  
 
 автор: Дядя Федор   (03.07.2012 в 13:37)   личное сообщение
 
 

Дык в varmas как раз строки.
varmas(0) - Первая строка
varmas(1) - вторая и т.д.

'Построчно в массив
    varmas = Split(param, Chr(13))
    For i = 0 To UBound(varmas) - 1
    Debug.Print varmas(i)
    Next

В чем проблема-то?
Строки можно разделить на слова
varmas2=split(varmas(i)," ")
и далее.

  Ответить  
 
 автор: час   (03.07.2012 в 14:08)   личное сообщение
 
 

Спасибо!
Всё хорошо!
осталось решить проблему как отбросить квадратики в конце вычленяемой строки
RTrim не помогает (
потому как код символа этого = 9

  Ответить  
 
 автор: Дядя Федор   (03.07.2012 в 14:30)   личное сообщение
 
 

По коду и убрать

  Ответить  
 
 автор: час   (03.07.2012 в 14:36)   личное сообщение
 
 

угу

  Ответить  
 
 автор: Дядя Федор   (03.07.2012 в 15:05)   личное сообщение
 
 


Public Sub tststststs()
Dim s$, s1$
Dim i, k
k = Asc("Х") 'X-это квадратик(здесь не отображается)
s = "123XXXXXX"
Debug.Print "s=" & s
For i = Len(s) To 1 Step -1
s1 = Mid(s, i, 1)
If Asc(s1) <> k Then
 s = Left(s, i)
 Exit For
End If
Next
Debug.Print "s=" & s
'Только у меня почему-то у квадратика код 7
End Sub

  Ответить  
 
 автор: час   (03.07.2012 в 15:08)   личное сообщение
 
 

  Ответить  
 
 автор: Дядя Федор   (03.07.2012 в 15:10)   личное сообщение
 
 

На славу порезвились. (Че-то сегодня на работе спокойно)

  Ответить  
 
 автор: час   (03.07.2012 в 23:13)   личное сообщение
 
 

Везёт тебе!!!

  Ответить  
 
 автор: kot_k_k   (04.07.2012 в 10:24)   личное сообщение
 
 

точно везет - у нас сервак тупит с утра - "потерял" доменные учетки - ни инету, ни вход на терминал - полная балалайка. адим с 7-30 дуреет ужо

  Ответить  
 
 автор: Дядя Федор   (04.07.2012 в 11:38)   личное сообщение
 
 

Так везло вчера. Сегодня какие-то глюки глупые в терминальных сеансах...

  Ответить  
 
 автор: kot_k_k   (04.07.2012 в 11:51)   личное сообщение
 
 

а-а-а-а-а, сегодня прадник "Международный День комповых глюков"

издревле в этот день все возможные глюки и баги Винды просыпаются, возрождаются дабы продемонстрировать забывшему миру их былую мощь.

  Ответить  
 
 автор: kot_k_k   (04.07.2012 в 15:24)   личное сообщение
 
 

ипать - валится винт на серваке, какого-то уя сделало откат файлов на 22 марта 2012 года, там типа файлообменник, почему не было зеркала - ХЗ, слава богу база на терминале - но пришлось срочно всем по новой воять учетки на терминале и по-новой файлы всем раздавать на подключение, мозк пухнет

  Ответить  
 
 автор: час   (05.07.2012 в 16:02)   личное сообщение
 
 

Я вот о чъём подумал...
А если ворда нет на компе...
Можно как то считать оттудыва строки.
Ну из xxx.doc ?

  Ответить  
 
 автор: Анатолий (Киев)   (05.07.2012 в 18:21)   личное сообщение
 
 

Если нет Ворда, то, скорее всего, есть ОпенОфис. Он умеет читать xxx.doc и сохранять в TXT, а уж его, я надеюсь, вы умеете читать построчно.
Кстати, так можно сделать и в Ворде - сохранить в TXT и его дерибанить.

  Ответить  
 
 автор: час   (05.07.2012 в 23:51)   личное сообщение
 
 

Спасибо!
Что, можно ворд сохранить как txt ?
Прям из ворда?
Или скопировать вставить?
===============================
Точно, умеет ворд текстовые файлы из своих записей варганить!!

  Ответить  
 
 автор: Дядя Федор   (06.07.2012 в 07:48)   личное сообщение
 
 

Файл-Сохранить как

  Ответить  
 
 автор: час   (07.07.2012 в 01:17)   личное сообщение
 
 

ага!

  Ответить  
 
 автор: Йожык   (09.07.2012 в 21:13)   личное сообщение
 
 

Но если тебе все-таки банковскую выписку надо было из RTF считать, то я бы тебе готовый модуль сбросил.
процедурка по выписке бегает, в таблице, и оплаченные счета в примечании выискивает и ИНН...
Потом по базе распихивает оплаты в полуавтомате. Девочка сидит проверяет, те ли счета, те ли реквизиты, те ли деньги :))
Но находится все само. ДРугое дело, что клиенты при оплате ошибаются.

  Ответить  
 
 автор: час   (10.07.2012 в 13:31)   личное сообщение
 
 

Спасибо!!!
Буду иметь.

  Ответить  
 
 автор: час   (30.07.2012 в 16:28)   личное сообщение
 
 

А как задать считывание строк до конца документа.
А то у меня при считывании когда уже считывать нечего - всё рушиться нафиг

  Ответить  
 
 автор: Анатолий (Киев)   (30.07.2012 в 18:54)   личное сообщение
 
 

Покажите код.

  Ответить  
 
 автор: час   (30.07.2012 в 20:22)   личное сообщение
 
 


Private Sub Комманда8_Click()
Dim STR_FILE As String
Dim STR_Filter  As String
Dim PROGRAMS_NAME As String

Dim rst As ADODB.Recordset

Dim STR_ID_KEY As String

' для документа
Dim APPWrd As Object
Dim oDoc1 As Object
Dim DOKS_PATCH As String
Dim STR_NACHALO As String
Dim DOKS As String
Dim DOKS1 As String


'Для циклов
Dim i As Integer
Dim F As Integer
Dim F1 As Integer

' хронология
Dim REG_PROD As Integer                       ' Регистрированные продукты
Dim PRO_NOMER As Integer                   'Производственный номер
Dim KOL_VO_PROGRAMM As Integer ' количество добавленных программ
Dim POVTOR  As String

   On Error GoTo Комманда8_Click_Error
   
   ' нулим переменные
POVTOR = ""
STR_ID_KEY = ""
Call CLEAR_FIELD
REG_PROD = 0
PRO_NOMER = 0
KOL_VO_PROGRAMM = 0


    STR_Filter = "Выбор файла (*.doc)" & Chr$(0) & "*.doc" & Chr$(0) & "All Files (*.*)" & Chr$(0) & "*.*" & Chr$(0)
    DOKS_PATCH = FileOpenSave(OFN_OVERWRITEPROMPT, App.path & "\IMPORT\", STR_Filter, , ".doc", , "Выбор файла", -1, True)
 
If NZVB(DOKS_PATCH) = "" Then
    MESS "Не выбран файл"
    Exit Sub
End If

STR_FILE = FUN_FILE_NAME(DOKS_PATCH)
STR_FILE = Mid(STR_FILE, 1, Len(STR_FILE) - 4)

        ' проверка наличия уже загруженного такого же ключа
Set rst = New ADODB.Recordset

rst.Open "SELECT KEY_TBL.* " _
& "  FROM KEY_TBL " _
& "  Where (((KEY_TBL.KEY_NAMBER)  =  '" & STR_FILE & "')) ", GLB_CONNECTION, adOpenKeyset, adLockOptimistic


        If Not rst.EOF And Not rst.BOF Then
            MESS "Такой ключ уже загружен! " & vbCrLf & "Добавим только новые программы."
            STR_ID_KEY = rst("ID_KEY")
            Me!ID_KEY = rst("ID_KEY")
            Me!KEY_NAMBER = rst("KEY_NAMBER")
          
            GoTo TOKA_PROGRAMMI  'Такой ключ уже загружен грузим только программы
        End If
        ' проверка наличия уже загруженного такого же ключа

' загрузка нового ключа
Set rst = New ADODB.Recordset
' новая запись
rst.Open "SELECT KEY_TBL.* From KEY_TBL ", GLB_CONNECTION, adOpenKeyset, adLockOptimistic

STR_ID_KEY = FUN_GENERATE
rst.AddNew
        rst("ID_KEY") = STR_ID_KEY
        rst("KEY_NAMBER") = STR_FILE
        rst("USER_NAME") = GLB_USER_NAME
        rst("DATE_RECORDS") = Date
rst.UpdateBatch ' запомнить


Me!ID_KEY = STR_ID_KEY
Me!KEY_NAMBER = STR_FILE
           rst.Close
             Set rst = Nothing


  'Грузим только программы
TOKA_PROGRAMMI:

STR_NACHALO = 0 ' строка "Регистрированные продукты" ещё не найдена

'Чтение файла xxx.DOC
    Set APPWrd = CreateObject("Word.Application")
   ' APPWrd.Visible = False
    Set oDoc1 = APPWrd.Documents.Open(DOKS_PATCH)

'Построчное чтение файла
    With oDoc1                                 ' .Parent.Visible = True

                                      ' Чтение сток документа
       For i = 1 To 100 ' строки документа от балды шукаем 100 строк
'       On Error GoTo m1
Me!KOLVO = i
Me!KOLVO.Refresh

' ВЫЯВИТЬ конец  документа
'If oDoc1.ActiveWindow.Selection.End Then MsgBox "Конец"
'If oDoc1.Content.End Then MsgBox "Конец"
'If oDoc1.ActiveWindow.Selection.End = oDoc1.Content.End Then MsgBox "Конец"
       
       DOKS = NZVB(.Paragraphs(i))
       ' если пустая строка
      If NZVB(DOKS) = "" Then GoTo dalee
      ' если уже пошли строки программ
      If STR_NACHALO = 1 Then GoTo Pognali
       
            If InStr(1, NZVB(DOKS), "Производственный номер", vbTextCompare) <> 0 Then
                ' сравнение номера ключа
                If InStr(1, NZVB(DOKS), KEY_NAMBER, vbTextCompare) = 0 Then
                    MESS "Не верно указан документ!"
                    oDoc1.Close
                    APPWrd.Quit
                    Exit Sub
               End If
               PRO_NOMER = 1
               GoTo dalee:
            End If

            If InStr(1, NZVB(DOKS), "Регистрированные продукты", vbTextCompare) <> 0 Then
                   STR_NACHALO = 1 'Если найден идентиф. начала считывания ' начало строк
                   REG_PROD = 1
                    GoTo dalee:
                End If

Pognali:
'Если идентиф. начала считывания STR_NACHALO = 1 , то погнали
If STR_NACHALO = 1 Then

' считывание
DOKS1 = ""

DOKS = Replace(DOKS, Chr(9), " ")
DOKS = Replace(DOKS, Chr(10), " ")
DOKS = Replace(DOKS, Chr(13), " ")
DOKS = LTrim(DOKS)
DOKS = RTrim(DOKS)
 If NZVB(DOKS) = "" Then GoTo dalee
' создание строки кода ключа
     For F1 = 1 To Len(DOKS)
     If Asc(Mid(DOKS, F1, 1)) <= 57 And Asc(Mid(DOKS, F1, 1)) >= 48 Or Asc(Mid(DOKS, F1, 1)) = 32 Then
        DOKS1 = DOKS1 & Mid(DOKS, F1, 1)
     End If
    Next F1
DOKS1 = LTrim(DOKS1)
DOKS1 = RTrim(DOKS1)
' создание строки наименования программы
PROGRAMS_NAME = Mid(DOKS, 1, Len(DOKS) - Len(DOKS1))
PROGRAMS_NAME = LTrim(PROGRAMS_NAME)
PROGRAMS_NAME = RTrim(PROGRAMS_NAME)

DOKS = ""
' простановка пробелов
If NZVB(DOKS1) <> "" Then
    If InStr(1, DOKS1, " ", vbTextCompare) = 0 Then
         For F1 = 1 To Len(DOKS1)
            If Asc(Mid(DOKS1, F1, 1)) <= 57 And Asc(Mid(DOKS1, F1, 1)) >= 48 Then
                 DOKS = DOKS & Mid(DOKS1, F1, 1)
                 If F1 / 5 = Int(F1 / 5) Then
                    DOKS = DOKS & " "
                End If
            End If
        Next F1
        Else
        DOKS = DOKS1
    End If
    
    Else
    MESS "Не распознан код продукта (программы)! " & PROGRAMS_NAME
    POVTOR = "Не распознан код продукта (программы)! "
    Exit Sub
End If


' проверка программы на наличие в базе
Set rst = New ADODB.Recordset

rst.Open "SELECT PRODUKT_TBL.* From PRODUKT_TBL " _
& " WHERE (((PRODUKT_TBL.ID_KEY)='" & STR_ID_KEY & "') AND ((PRODUKT_TBL.PRODUKT_NAME)= '" & PROGRAMS_NAME & "'));", GLB_CONNECTION, adOpenKeyset, adLockOptimistic

If Not rst.EOF And Not rst.BOF Then
MESS "Повтор загрузки! " & PROGRAMS_NAME & vbCrLf & "Загрузка отменена."
POVTOR = "  Повтор загрузки " & PROGRAMS_NAME
GoTo dalee
End If

Set rst = New ADODB.Recordset

rst.Open "SELECT PRODUKT_TBL.* " _
& " From PRODUKT_TBL ", GLB_CONNECTION, adOpenKeyset, adLockOptimistic

rst.AddNew
    rst("ID_PRODUKT") = FUN_GENERATE
    rst("ID_KEY") = STR_ID_KEY
    rst("PRODUKT_NAME") = PROGRAMS_NAME
    rst("PRODUKT_NAMBER") = DOKS
    rst("USER_NAME") = NZVB(GLB_USER_NAME)
    rst("DATE_RECORDS") = Date
    rst.UpdateBatch
    KOL_VO_PROGRAMM = KOL_VO_PROGRAMM + 1
End If

dalee:
       Next i   ' строки документа
   End With


FINISH:

Call FRM_OKNO_KEY.IN_EKRAN_KEY
Call FRM_OKNO_KEY.IN_EKRAN_PROGRAM
Me!KOLVO = KOL_VO_PROGRAMM

' переносфайла в другую папку
STR_FILE = FUN_FILE_NAME(DOKS_PATCH)
If FUN_COPY_FILE(App.path & "\IMPORT\", STR_FILE, App.path & "\IMPORT\Обработано\") = True Then
'сохранить как
'oDoc1.SaveAs App.path & "\IMPORT\Обработано\Обработано_" & STR_FILE

Call FUN_DELETE_FILE_NAME(App.path & "\IMPORT\" & STR_FILE) ' , App.path & "\IMPORT\Обработано\" & STR_FILE)
End If
             oDoc1.Close
              APPWrd.Quit

            

' ----------------------------------------------------
   On Error GoTo 0
   Exit Sub

Комманда8_Click_Error:

If REG_PROD = 0 Then
MESS "Не найдена строка   " & vbCrLf & " (Регистрированные продукты:)  "
End If

If PRO_NOMER = 0 Then
MESS "Не найдена строка  " & vbCrLf & " ( Производственный номер: ) "
End If

MESS STR_FILE & vbCrLf & POVTOR
MESS "Удалось добавить программ - " & vbCrLf & KOL_VO_PROGRAMM & "шт."
Me!SEACH_KEY = STR_FILE
Call FRM_OKNO_KEY.IN_EKRAN_KEY
Call FRM_OKNO_KEY.IN_EKRAN_PROGRAM
Me!KOLVO = KOL_VO_PROGRAMM
  Set rst = Nothing
'oDoc1.Close
'APPWrd.Quit
Call FUN_IN_TXT(FUN_Patch_File(App.path, "Error.txt"), "ошибка " & Err.Number & " (" & Err.Description & ") в процедуре Комманда8_Click из Form FRM_OKNO_KEY")
End Sub

  Ответить  
 
 автор: час   (31.07.2012 в 12:47)   личное сообщение
 
 

Приспособился так:
Открывая документ - перехожу в конец дока и пишу там слово - Конец.
дойдя по строкам до этого места вижу - что нашёл!

  Ответить  
 
 автор: kot_k_k   (31.07.2012 в 14:27)   личное сообщение
 
 

прочти символы после священного слова "Конец" - и значит эти символы означают окончание текста - значит в следующий раз можно искать эти символы, а не возится с концом.

  Ответить  
 
 автор: час   (31.07.2012 в 15:32)   личное сообщение
 
 

Фигвам симвалав нету.
Потому при обработке ентого конца и вываливаемся в ошибку.
Нечего считывать - вот и ошибон.
А када есть чего - другое дело.
надо тока что то иное туда писать. что бы не заметно було!
А вот что???

  Ответить  
 
 автор: ser60   (01.08.2012 в 07:36)   личное сообщение
 
 

а если оставить слово "конец", но сделать его невидимым в ворде? (печататься слово "конец" тоже не будет.

  Ответить  
 
 автор: час   (01.08.2012 в 08:52)   личное сообщение
 
 

Можно и так, если знать - как.
Шрифт белый забабахать, наверное.
Спасибо за идею.

  Ответить  
 
 автор: ser60   (02.08.2012 в 05:30)   личное сообщение
48 Кб.
 
 

через шрифт

  Ответить  
 
 автор: час   (02.08.2012 в 15:58)   личное сообщение
 
 

вот ведь как просто.
осталось програмно это написать.
А с другой стороны.
Вдруг документ кто нить захочет дополнить.
Хотя пусть дополняет. Конец, он и в африке....

  Ответить  
 
 автор: snipe   (02.08.2012 в 16:22)   личное сообщение
 
 

MS Word автоматически устанавливает следующие закладки:
\StartOfDoc - начало документа;
\EndOfDoc - конец документа;

  Ответить  
 
 автор: час   (03.08.2012 в 10:18)   личное сообщение
 
 

Ясно. Спасибо.
Осталось понять как нащупать эту закладку.

  Ответить  
 
 автор: snipe   (03.08.2012 в 12:14)   личное сообщение
 
 

Определение текущего положения курсора
лист
в1=Selection.Information(1)
позиция в строке
в2=Selection.Information(9)
строка
в3=Selection.Information(10)

лезем на закладку конец документа
определяем позицию курсора (лист, строка, позиция в строке)
запоминаем
лезем на закладку начало документа, передвигаемся по документу
и сравниваем с текущее положение и запомненные значения

P.S функции написаны в Вордовском VBA

  Ответить  
 
 автор: час   (03.08.2012 в 12:54)   личное сообщение
 
 

Да?!
папробую применить.
Спасибо.
Ты чё, уже отработал?

  Ответить  
 
 автор: snipe   (03.08.2012 в 12:59)   личное сообщение
 
 

ага

  Ответить  
 
 автор: kot_k_k   (03.08.2012 в 15:57)   личное сообщение
 
 

блин еще 1,5 часа и потом тока

  Ответить  
HiProg.com - Технологии программирования
Rambler's Top100 TopList