Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как найти строку в файле?

248
15 августа 2007 года
Dmitry2064
590 / / 06.12.2006
Такой вроде бы простой вопрос. Я определил значение 2-х строковых переменных. Точно такие же надо найти в другом файле. Вернее надо сначала найти одну переменную (L1), потом попытаться найти вторую переменную (L2) [но уже только в пределах той строки текста, где оказался курсор], а если ее нет, то выделить всю строку, в которой L1 являлась подстрокой и присвоить эту строку новой переменной и потом вернуться в исходный файл.
Вот можно ли хотя бы подсказать, как это пишется? (не все, конечно, а именно инструкция для поиска).
На данный момент мои познания ограничиваются этим (благосклонно подсказали форумчане):

 
Код:
Open "C:\slovar.txt" for Input as #1
Do While Not EOF(1)    ' Loop until end of file.
    Line Input #1, TextLine    ' Read line into variable.
    MsgBox TextLine
    Debug.Print TextLine    ' Print to the Immediate window.
Loop
Close #1    ' Close file

Т.е. могу пока только считывать строки файла.

Спасибо большое.

P.S. На самом деле, надо бы не просто найти L1 и вслед за ней L2. Надо найти L1, потом либо найти L2 далее на этой же строчке, либо продолжить поиск L1 по документу дальше и снова повторить поиск подстроки L2. И так пока в каком-нибудь L1 не окажется L2. А если так и не оказалось, то вернуться к первому (оно же должно быть и единственным, раз L2 не нашлось) найденному значению L1, и уже всю строку, где L1 нашлось отправить в качестве новой переменной в дальнейшую обработку.

P.S.S. Текст в P.S'e я написал скорее для себя, что бы примерно знать, чего добиваться от программки.
248
15 августа 2007 года
Dmitry2064
590 / / 06.12.2006
А можно, видимо и просто сделать (открыть) файл для поиска как другой ворд-файл и искать там уже банальным образом. Попробую так.
Хотя если кто захочет подсказочку подбросить, то скажу спасибо.
5.9K
15 августа 2007 года
SPB-667
119 / / 23.06.2007
Надеюсь, этот код как раз то, что тебе нужно:

Код:
Dim TextLine As String
Dim C As Boolen
Dim X AS String    

C=False
1:
Open "C:\slovar.txt" for Input as #1
Do While Not EOF(1)        
    Line Input #1, TextLine
    Select Case C
       Case True:  If InStr(TextLine, L1)>0 Then X=TextLine: Exit Do
       Case False: If InStr(TextLine, L1)>0 Then If InStr(TextLine, L2)>0 Then X=TextLine: C=True: Exit Do
    End Select    
Loop
Close #1
If C=False Then C=True: GoTo 1
251
16 августа 2007 года
SkyMаn
1.7K / / 31.07.2007
Цитата: Dmitry2064
P.S.S. Текст в P.S'e я написал скорее для себя, что бы примерно знать, чего добиваться от программки.


Напиши, пожалуйста и для меня, чтобы примерно понять твой вопрос:D
Приведи пример файла, в котором должен осуществляться поиск. Приведи примеры значений переменных L1 и L2. И да будет тебе код.

251
16 августа 2007 года
SkyMаn
1.7K / / 31.07.2007
Цитата: SPB-667
Надеюсь, этот код как раз то, что тебе нужно:

 
Код:
....
[COLOR=red]1:[/COLOR]
...
If C=False Then C=True: [COLOR=red]GoTo 1[/COLOR]


А разве GoTo еще не умер? Имхо, давно пора отказаться от этого паразита))
Тем более, что ваш пример даст бесконечное зацикливание программы. Сами-то пробовали?

5.9K
16 августа 2007 года
SPB-667
119 / / 23.06.2007
Цитата: SkyM@n
А разве GoTo еще не умер? Имхо, давно пора отказаться от этого паразита))
Тем более, что ваш пример даст бесконечное зацикливание программы. Сами-то пробовали?



SkM@n, во-первых, кому не нравится оператор GoTo, тот пусть использует что-нибудь другое, - это, как говорится, дело каждого, но лично меня он вполне устраивает; а, во-вторых, я сам не испытывал этот код, но "бесконечного зацикливания пограммы" точно не будет; посмотри, пожалуйста, внимательней! :)

248
16 августа 2007 года
Dmitry2064
590 / / 06.12.2006
Цитата: SkyM@n
Напиши, пожалуйста и для меня, чтобы примерно понять твой вопрос:D
Приведи пример файла, в котором должен осуществляться поиск. Приведи примеры значений переменных L1 и L2. И да будет тебе код.


И так.
Есть контрольный файл (slovar.doc) с названиями из которого надо сравнивать названия из обрабатываемого файла. Т.е. в обрабатываемом файле слова (из контрольного файла) будут встречаться (как правило) в неименительном падеже в таком виде:

Цитата:
... В последнем квартеле текущего года «Астраханскому корабелу» [COLOR="Navy"]{ XE "«Астраханскому корабелу»" }[/COLOR] удалось ликвидировать свою задолженность перед бюджетом....


Черный жирный текст - это текст, который читатель видит, а синим выделен служебный текст (невидимый), который является входом указателя, который и должен быть сгенерирован в конце всей работы из таких вот отдельных "вхождений", но только в именительных падежах - [COLOR="DarkRed"]Астраханский корабел[/COLOR].
Ниже я привел пример одинаковых [COLOR="DarkGreen"]начал [/COLOR]названий, но разных [COLOR="DarkGreen"]полных [/COLOR]названий
А вот, то, что удалось пока написать.

Код:
Sub Entries()    
     Dim Pos As String, L1 As String, L2 As String, L3 As String
     '
     Selection.HomeKey Unit:=wdStory 'ищем коды полей - входы указателей
     Selection.Find.ClearFormatting
     With Selection.Find
             .Text = "^d": .Replacement.Text = "": .Forward = True: .Wrap = wdFindContinue: .Format = True
     End With
     Selection.Find.Execute
     L1 = Left$(Selection.Words(4), 3)
     L2 = Left$(Selection.Words(5), 3)
     If L2 = Str(34) & Str(32) Then 'если кавычка с пробелом, то прекращаем запоминать начала слов
     GoTo sk
     End If
     L3 = Left$(Selection.Words(6), 3)
     If L3 = Str(34) & Str(32) Then 'если кавычка с пробелом, то опять прекращаем запоминать начала слов
     GoTo sk
     End If
     
     sk:
'Теперь надо из полученных L1-L3 найти соответствие в словаре
' и только потом уже выполнить Selection=PosNew
' Т.е. надо искать строку L1 в словаре, если нашлась, то в этой же
' строчке искать L2 и если найдено, то тут же искать L3
'потом всю строку загонять в переменную PosNew
' и возвращаться в исходный док.
     End Sub


Пример слов в словаре:
Ассоциация европейского бизнеса в России
Ассоциация российских банков
Ассоциация транзита Эстонии
Соответственно L1, L2, L3 будут выглядеть как "Асс, "евр", "биз" для первого вар-та, "Асс", "рос", "бан" для второго и т.д.
[COLOR="DarkGreen"][только сейчас сообразил, что еще могут встречаться названия из одного слова, но все равно разные (Астраханьгазпром,
Астраханьэлектропассажиртранс и т.п.). Но это уже потом я сам может быть доделаю][/COLOR]

P.S. А бесконечных циклов мы не боимся. Всегда есть Ctrl-Break...
5.9K
16 августа 2007 года
SPB-667
119 / / 23.06.2007
Цитата: Dmitry2064

P.S. А бесконечных циклов мы не боимся. Всегда есть Ctrl-Break...



Это то да, но в EXE-файле CTRL+BREAK не поможет! :D

251
16 августа 2007 года
SkyMаn
1.7K / / 31.07.2007
Я так и не понял... Ты только все усложнил. Мне надо было так: что есть, и что надо. А тут еще и корабли поплыли...:eek:
248
16 августа 2007 года
Dmitry2064
590 / / 06.12.2006
В тексте обрабатываемого документа встречаются названия, которые перечислены в slovar.doc (или slovar.txt - не знаю, в каком лучше формате держать словарь). Вот надо найти все помеченные для указателя слова/словосочетания (помечается в Ворде так: меню-вставка-ссылка-оглавление и указатели-кнопка "пометить") и перевести их в [COLOR="Navy"]именительный падеж[/COLOR] (ориентируясь на slovar). А при отсутствии образца в словаре (ну вдруг попадется "Урюпинскнефтегаз") занести уже обратно в словарь, причем лучше как раз не по алфавиту, чтобы можно было бы сразу, не разыскивая там, подправить на именит. падеж.

Т.е. проще говоря, задача заключается в том, чтобы создать алгоритм перевода любых падежей в именительный. НО. Это, как мне кажется явно сложнее, нежели сравнивать со словарем, где все и так уже в именит. падежах.

Сокращенный вариант примера обрабатываемого текста в приложенном файле.
248
16 августа 2007 года
Dmitry2064
590 / / 06.12.2006
Цитата: SPB-667
Это то да, но в EXE-файле CTRL+BREAK не поможет! :D



До exe-шек я еще не дожил :o . Пока все только из-под Ворда.
А код сейчас погляжу. Спасибо большое.

248
17 августа 2007 года
Dmitry2064
590 / / 06.12.2006
Цитата: SPB-667
Это то да, но в EXE-файле CTRL+BREAK не поможет! :D


Сработало без зацикливания (чему я оч. рад).
Правда не смог понять смысл Case True/False. Вроде бы обе строки начинаются одинаково... Видно это не для моих мозгов (пока).

А как бы еще вписать сюда проверку на наличие начала 3-го слова (если таковое имеется - для трехсловных названий)?
А если не находится ни однословное, ни двусловное, ни трехсловное совпадения, то вписать исходное название в словарь.

И вообще, как оказывается, задачка сильно не тривиальная. Т.к. чует мое сердце, должна быть куча вложенных циклов проверки. Сначала проверять совпадения посимвольно на первом слове (но, что примечательно, без окончания :eek: , потом пословно (если первое совпало), а если совпадает все, кроме последнего слова или его куска (или не совпадает ничего), то записывать исходный текст как новое вхождение словаря (кстати лучше ставить не по алфавиту [что сильно упрощает жизнь], т.к. потом проще найти все новые слова, которые оказались вписанными и уже ручками их перевести в именит. падеж.).
Вобщем сдается мне, что эта задачка тянет на отдельную программную разработку, за которую можно просить деньги. :(

248
17 августа 2007 года
Dmitry2064
590 / / 06.12.2006
Вписал инструкцию для внесения в словарь не найденной строки (выделено жирным):
Код:
Open "C:\Verstka\Beliakov\slovar.txt" For Input As #1
Do While Not EOF(1)    ' Loop until end of file.
    Line Input #1, TextLine    ' Read line into variable.
    If InStr(TextLine, L1) > 0 Then
        If InStr(TextLine, L2) > 0 Then
           Pos = TextLine 'эту POS потом воткнем на свое место в обрабатываемом файле
           Exit Do
        End If
    Else
    Close #1
    Open "C:\Verstka\Beliakov\slovar.txt" For Append As #1
    Print #1, L
    End If
    Debug.Print TextLine    ' Print to the Immediate window.
Loop
Close #1    ' Close file

Потратив 50 минут сам сообразил, как дописывать в конец файла и в какой момент это делать.
5.9K
17 августа 2007 года
SPB-667
119 / / 23.06.2007
Переменную С я использовал для того, что бы программа "знала", что файл уже был прочитан полностью один раз, и эта переменная имеет смысл только тогда, когда не находится переменная L2.

Что касается твоего варианта, не могу понять откуда взялась переменная L и каков её смысл, может быть, ты имел в виду L1? :confused:
248
18 августа 2007 года
Dmitry2064
590 / / 06.12.2006
Цитата: SPB-667
Переменную С я использовал для того, что бы программа "знала", что файл уже был прочитан полностью один раз, и эта переменная имеет смысл только тогда, когда не находится переменная L2.


Сейчас подумаю и пойму... :o

Цитата:

Что касается твоего варианта, не могу понять откуда взялась переменная L и каков её смысл, может быть, ты имел в виду L1? :confused:



[COLOR="Navy"]L[/COLOR] взялась из предыдушего (непоказанного) кусочка кода (ведь переменные L1-L3 - только 3х-буквенные начальные фрагменты слов). А в [COLOR="Navy"]L[/COLOR] я пишу первично найденное целое словосочетание. Потом я его очищаю (left'ами и right'ами) от Вордовских служебных символов, являющихя разметкой указателя, и остается голенькое словосочетание, которое надо запомнить в отдельной переменной на случай НЕнахождения "похожего" в словаре :mad:. И тогда саму ее ([COLOR="Navy"]"L"[/COLOR]) туды, - в словарь.

5.9K
19 августа 2007 года
SPB-667
119 / / 23.06.2007
Ну, теперь становится всё на свои места...
И что в итоге, программа правильно работает?
248
21 августа 2007 года
Dmitry2064
590 / / 06.12.2006
Цитата: SPB-667
Ну, теперь становится всё на свои места...
И что в итоге, программа правильно работает?



Ну это же только часть. Так она будет находить только первое встретившее словосочетание. А надо же найти все "входы указателя". Но это опять же только часть. Потому что могут быть однословные вхождения. Например Астраханьгазпром и Астраханьмяспром будут обработаны одинаково и первое слово воткнется на место второго. Т.е. сравниваться со словарем надо бы не только по словам, но и по символам (а потом уже и по словам). Вобщем это морока. Непростая задачка.

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

:(

248
13 сентября 2007 года
Dmitry2064
590 / / 06.12.2006
Как передать в строку кавычку (Alt-034)? На функцию Chr(34) говорит, что Wrong Number of argument or invalid property assignment.
251
13 сентября 2007 года
SkyMаn
1.7K / / 31.07.2007
Цитата: Dmitry2064
Как передать в строку кавычку (Alt-034)? На функцию Chr(34) говорит, что Wrong Number of argument or invalid property assignment.


Chr(34) = символ " (кавычка). А что там выдает без кода и без возможностей телепатии определить трудно.;)

7
13 сентября 2007 года
@pixo $oft
3.4K / / 20.09.2006
Цитата: SPB-667
Это то да, но в EXE-файле CTRL+BREAK не поможет! :D


От всех невзгод и бед поможет ресет!Или Shift+Ctrl+Esc
А ещё,чтобы написать кавычку,можно написать 2 кавычки,типа

 
Код:
MsgBox "Эта строка содержит символ "",номер которому 34"
251
13 сентября 2007 года
SkyMаn
1.7K / / 31.07.2007
Или
[LEFT]MsgBox "Эта строка содержит символ "+chr$(34)+",номер которому 34"[/LEFT]
248
13 сентября 2007 года
Dmitry2064
590 / / 06.12.2006
Вот как я собираю куски в единую строку
Newnum = "newdata = " & "«" & LTrim$(Str$(Numm)) & "»" & vbCrLf & "return newdata"
Вот надо вместо символа « и » поставить простые кавычки ", т.к. элемент LTrim$(Str$(Numm)) содержит трехзначное число, кот. должно быть заключено в кавычки. Т.е.
должно получаться так:
newdata="674"
return newdata


А VBA ругается на такую простенькую инструкцию:
[COLOR="Navy"]C$ = Chr(34)
ИЛИ
С=Chr$(34)
[/COLOR] и в любых сочетаниях со знаком доллара (перед этим все объявлено как строка)

Опять же пишет:
[COLOR="Red"]Wrong Number of argument or invalid property assignment.[/COLOR]
251
13 сентября 2007 года
SkyMаn
1.7K / / 31.07.2007
скорее всего у тя уже такая ф-ция есть
248
13 сентября 2007 года
Dmitry2064
590 / / 06.12.2006
Вот как пришлось сделать:
пишу в переменную эту кавычку и потом в собираемую строку сую полученную переменную. И все. Некрасиво, зато работает, скотина :) .

Код:
Open "C:\Verstka\Tiraz.spt" For Input As #1
Line Input #1, TextLine    ' Read line into variable.
    Q = Mid$(TextLine, 9, 1) 'выудили кавычку
    Num = Mid$(TextLine, 10, 3) 'номер
    Numm = Val(Num) + 1 'увеличили на единичку
    'strNumm = LTrim$(Str$(Numm)) 'отсекли лидирующий пробел
    Newnum = "newdata=" & Q & LTrim$(Str$(Numm)) & Q & vbCrLf & "return newdata"
    MsgBox Newnum
Close #1    ' Close file.
    Open "C:\Verstka\Beliakov\Tiraz.spt" For Output As #1
    Print #1, Newnum
Close #1    ' Close file


Обработка была такого текста:
[COLOR="Navy"]newdata="674"
return newdata[/COLOR]

Т.е. в результате номер стал не 674, а 675, что и требовалось весь день....

Всем спасибо за уделённое время. Во время нашего диалога мозги работают лучше
251
13 сентября 2007 года
SkyMаn
1.7K / / 31.07.2007
скажи,
msgbox chr(34)&chr(32)&chr(34)
работает?
248
13 сентября 2007 года
Dmitry2064
590 / / 06.12.2006
Цитата: SkyM@n
скажи,
msgbox chr(34)&chr(32)&chr(34)
работает?


Прошу прощения, что не сразу отвечаю.
Не работает. Снова подсвечивает chr и опять свое талдычит [COLOR="Red"]Wrong Number of argument or invalid property assignment[/COLOR].
Я стал искать по help'у, нашел ссылку на chr команду, а когда щелкаю, оно просит доустановить помощь по VB и не может найти файл установки именно для VB по этому разделу. По другим разделам вроде всегда помощь открывается. Т.е. может быть у меня какая-то урезанная версия чего-то там. А вот в 5-меговом VB пишу такую команду и все нормально отвечается. Т.е., видимо, какие-то нюансы в версии, которая у меня в Вроде сидит.

251
13 сентября 2007 года
SkyMаn
1.7K / / 31.07.2007
Скорее всего у тебя в программе используется еще одна ф-ция chr, которая принимает не такое кол-во параметров. найди ее и переименуй. Нажми F2 и поищи ее.
5.9K
14 сентября 2007 года
SPB-667
119 / / 23.06.2007
Или, если не получится, попробуй использовать chr$()
248
14 сентября 2007 года
Dmitry2064
590 / / 06.12.2006
Цитата: SPB-667
Или, если не получится, попробуй использовать chr$()


А все равно. Что со знаком доллара, что без него.
Хотя вот в соседнем топике написал вот так:
[COLOR="Navy"]With Selection.Find
.Font.Name = "Times New Roman"
'.Text = Udar$
.Text = Chr(161) 'символ Ў
.Replacement.Text = "!!!"
.Forward = True
.Wrap = wdFindStop
.Format = True
End With
Selection.Find.Execute Replace:=wdReplaceAll[/COLOR]
И работает.

Нашел! Записал этот код в Ворде на одном ноуте - и работает без проблем.
Тот же код записал на втором (рабочем) - пишет, что "неверная функция". Хотя дистрибутив Офиса один и тот же. А вот версии ХР на ноутах разные (обе лицензионные). [COLOR="Red"]НЕ работает на более поздней версии Виндов.[/COLOR]

251
14 сентября 2007 года
SkyMаn
1.7K / / 31.07.2007
Цитата: SPB-667
Или, если не получится, попробуй использовать chr$()


Автор топа уже говорил, что е него ни chr, ни chr$ не работает. А разницу-то знаете в данных ф-циях?

251
14 сентября 2007 года
SkyMаn
1.7K / / 31.07.2007
Цитата: Dmitry2064
Нашел! Записал этот код в Ворде на одном ноуте - и работает без проблем.
Тот же код записал на втором (рабочем) - пишет, что "неверная функция". Хотя дистрибутив Офиса один и тот же. А вот версии ХР на ноутах разные (обе лицензионные). [COLOR=red]НЕ работает на более поздней версии Виндов.[/COLOR]


2Dmitry2064: Я уже вам очередной раз повторяю, что скорее всего у вас данная ф-ция используется уже. Например, в надстройках. То есть. В ворде установлена другая надстройка, где определена прльзовательская функция chr с параметрами, отличными от реальной chr. То есть своего рода перезапись встроенной ф-ции на свою, пользовательскую. Поэтому, при обращении к chr(....) на самом деле идет обращение к новой пользовательской ф-ции, которая матерится, так как ей параметры не подходят. Рекоммендую: Отключить все надстройки, если не поможет, проверить, чтобы были подключена библиотека (Tools->Refrences), Visual Basic For Applications. Ее отключить вряд ли получиться в принципе, но проверь все же. А в ХР-версии все там работает.

5.9K
14 сентября 2007 года
SPB-667
119 / / 23.06.2007
Принципиальной разницы, конечно, нет, но, видимо, если символ оказывается числом, то в случае с chr$ он будет являться строкой.
248
14 сентября 2007 года
Dmitry2064
590 / / 06.12.2006
To SkyM@n.

Да, действительно. Я задал поиск по всему листу с макросами и нашел [COLOR="Red"]Sub Chr()[/COLOR]! [исправил на chrr()].
Спасибо большое. (а то сразу я не понял, что значит "функция используется"). Хотя VBA мог бы и запретить давать такое имя :cool:
251
14 сентября 2007 года
SkyMаn
1.7K / / 31.07.2007
Цитата: Dmitry2064
Хотя VBA мог бы и запретить давать такое имя :cool:


Ага, конечно мог бы. В самом, кстати, Visual Basic'е есть проверка на дублирование...
А можно поинтересоваться, почему у вас столько работы с VBA?

248
15 сентября 2007 года
Dmitry2064
590 / / 06.12.2006
Цитата: SkyM@n
А можно поинтересоваться, почему у вас столько работы с VBA?



Мне надо за два дня сверстать кучу документов (30-35 штук). Поэтому стараюсь в Ворде их максимально подготавливать (стили, предлоги, шрифтовые начертания, ед. измерения, годы, таблицы, картинки и пр.), чтобы в самой верстке было меньше работы и, самое главное, правки. Т.е. задача - уменьшить (а лучше совсем исключить :cool: ) кол-во возможных диалогов (и с машиной :( и с редактором :mad: ).
:rolleyes:

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог