Как удалить строку в текстовом файле vba

Обновлено: 07.07.2024

Ну, учимся работать с текстовыми файлами. Это нам нужно, чтобы прочитать существующий файл, изменить его, или создать свой. Крому того, в текстовом файле удобно хранить служебные данные собственной программы, например установки пользователя, результаты обработки данных и т.п.
Текстовой файл, собственно по названию, содержит в себе текстовые символы, ну и символы типа возврат каретки или перевод строки. Традиционно они имеют расширение .txt для текста, .dat для данных, .bat для исполняемых (командных) файлов, ну Windows еще использует .ini, .log, .inf. Читать и записывать их надо последовательно, символ за символом, начиная с первого.

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

Для открытия файла используется оператор Open. Синтаксис его такой:

Примечание: для открытия файлов прямого доступа, или двоичных файлов оператор Open содержит еще кое-какие аргументы, но сейчас мы их не используем и опускаем.

СЧИТЫВАНИЕ из текстового файла.

Создадим новый .exe проект в какой-нибудь папке и в ту же папку положим небольшой текстовой файл (у меня например "Справка.txt"). На форме разместим кнопку Command1 и текстовое поле Text1. В свойствах Text1 свойство Multiline поставим в True (чтобы текст переносился по строкам), а свойство ScrollBars в 2 - Вертикаль (чтобы можно было прокручивать текст, если он не уместился) смотри рис.15.



Рисунок 15.
Откроем окно кода и в (Genarel) объявим переменные F для хранения номера свободного файла, MyText и AllMyText - для хранения считываемого текста:

Dim F As Long
Dim MyText As String
Dim AllMyText As String

Создадим прцедуру Command1_Click() (щелкнув мышью по Command1 в выпадающем списке в окне кодов в верхнем левом поле, там где (General)). В теле образовавщейся процедуры. Можно также щелкнуть два раза по кнопке Command1 в режиме Объект и перейти в режим Код - там появится нужная нам процедура.

Private Sub Command1_Click()

Напишем для определения номера свободного файла

F = FreeFile

и откроем файл для чтения

Обратите внимание, что для указания пути файла мы опять используем функцию App.Path. Если бы мы написали просто "c:\VB\example\Справка.txt", то при переносе нашей паки с программой на другой диск или компьютер этот путь оказался бы ложным. А функция App.Path всегда возвращает путь, где лежит наша программа. Только перед именем файла не забывайте ставить обратный слеж (\), иначе запись работать не будет.
Для считывания строки текста существует оператор Line Input. Попробуем считать с его помощью содержимое файла в переменную MyText :

Передадим значение MyText переменной в Text1, чтобы увидеть, что мы там считали:

Text1.Text = MyText

затем закроем файл

и запустим нашу программу. Когда мы нажмем кнопку Command1, то в Text1 появиться содержимое файла "Справка.txt". Проблема только в том, что, если,( как и случилось в нашем файле "Справка.txt"), при создании текста применялось нажатие кнопки ENTER (перевод строки), то оператор Line Input считает текст до этого знака и все, потому, что строка кончилась. Чтобы этого избежать, мы применим цикл и будем считывать строки до конца файла. Для этого придется разобраться с новым для нас циклом по условию Do. Loop.

Цикл по условию Do. Loop

Это очень простая вещь. Цикл работает до тех пор, пока не выполнится какое-нибудь условие. Например мы будем увеличивать переменную X до тех пор, пока оне не станет равной, например, 100. Для этого применяется аргумент Until:

Do Until x>=100
x=x+1
Loop

при этом когда цикл закончится x будет равно 100. Можно записать его по другому, при этом смысл работы цикла не изменится:

Do
x = x + 1
Loop Until x >=100

Можно цикл записать наоборот, и он будеn выполняться до тех пор, пока соблюдается какое-то условие. Для этого применяется аргумент While (делать, пока. ) :

Do While x < 100
x = x + 1
Loop

Do
x = x + 1
Loop While x < 100

Во всех четырех случаях результат будет один. Цикл остановится, когда X=100. Только надо обращаться с ними аккуратно. Если ты поставишь условие, которое изначально ложно, цикл не выполнится ни разу, и наоборот если условие будет истинно всегда, возникнет бесконечный цикл и программа по-сути зависнет. Вот этот цикл не будет выполняться:

Do While x =100
x = x + 1
Loop

а этот будет бесконечным

Do Until x < 0
x = x + 1
Loop

Ну а теперь используем наш цикл для считывания строк из файла до тех пор, пока не настанет конец файла. Чтобы узнать, достигнут ли конец файла, можно использовать функцию EOF(номер файла), которая примет значение True, как только конец файла будет достигнут. Теперь переделаем нашу процедуру следующим образом:

По строкам здесь:

1 - объявление нашей процедуры
2 - очистка Text1
3 - присваиваем переменной F свободный номер файла
4 - открываем файл "Справка.txt" для последовательного чтения
5 - цикл по условию: до тех пор пока не конец файла
6 - DO в цикле считываем каждую строчку
7 - Присоединяем очередную строку к Text1 и ставим перевод строки (vbCrLf) чтоб красиво было
8 - LOOP завершаем цикл
9 - закрываем наш файл
10- конец процедуры

Ну вот и готово.

Здесь все почти в точности, как и в предыдущем примере, только суть несколько другая.

ЗАПИСЬ в текстовой файл.


Как и для считывания, прежде, чем записывать в текстовой файл, нужно получить к нему доступ. Для этого используем оператор Open с ключевым словом Output.
Добавим на форму еще кнопку Command4. Создадим для нее процедуру и напишем там:

То есть, мы записываем содержимое нашего текстбокса (если там что-то есть. Считайте в текстбокс Text1 наш файл Справка.txt нажатием одной из кнопок Command1-Command3) в файл "Запись.txt". Затем закрываем файл и конец процедуре:

Private Sub Command6_Click()
Dim Chislo As Long ' числовая
Dim Stroka As String ' строковая
Dim Logika As Boolean ' логическая
Dim DDate As Date ' дата (не путайте с Data)

Добавление данных в текстовой файл.

Чтобы добавить данные в текстовой файл, не стирая имеющихся там, надо просто открыть файл с ключевым словом Append. Быстренько разберем это на примере. Для этого положим на форму последнюю кнопку Command7 и в ней напишем код:

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

Данные функции предназначены для работы с текстовыми файлами из VBA Excel.

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

Чтение текстового файла в переменную:

Комментарии

Могу написать макрос под заказ (платно)

Как можно задать строки для чтения/записи из txt?
Пример:
Есть файл txt
Прораб
Вася
Петя

Работники
Саша
Андрей
Коля

Необходимо занести имена прорабов в один массив arr1(), а имена работников в другой arr2(). Изменить имена рабочих и их количество и вернуть в txt новые значения. Т.е. массивы динамические, а идентифицируем начало и конец соответствующего массива в txt по шапке в начале и пустой строке в конце.

В UTF-8 сохранять так
Function SaveTXTfile(ByVal filename As String, ByVal txt As String) As Boolean
On Error Resume Next: Err.Clear
Set stream = CreateObject("ADODB.Stream")
stream.Type = 2 'text
stream.Charset = "utf-8"
stream.Open
stream.writetext Replace(txt, Chr(10), vbNewLine)
stream.savetofile filename, 2
End Function

Добрый день!
Помогите еще в одной вещи.
По дефолту пишет в ANSI, а нужно UTF-8

Neri, замените в коде

Добрый день!
У меня есть ячейка, в которой спомощью функции сцепить собраные несколько значений и исползуется символ переноса строки
Выглядит это примерно вот так:
=СЦЕПИТЬ(R3 & СИМВОЛ(10) & S3 & СИМВОЛ(10))
"Строка 1"
"Строка 2"
Как можно записать в файл, но чтобы каждая строка писалась с новой строки?

Добрый день. А кто подскажет, какие применять команды для поиска части текста в файле (.xml), потом копировать его и этим текстом переименовывать папку или файл этот же? Спасибо.

получится что-то типа такого:


(под своим макросом, добавьте код функции ChangeFileCharset)

помогите плиииз решить задачку . у меня есть файл Эксель, мне его надо сохранить как текстовый с кодировкой Unicode, но при сохранении в этом формате програма добавляет две пустые строки, мне удалось убрать две пустые строки, но теперь он в конце первой строки ставит какой то символ, который я никак не могу убрать. где ошибка

Никто не спорит, - улучшать (дорабатывать) функцию можно бесконечно.
Чтобы нужные строки из файла брались, - кода будет в несколько раз больше.

Можете сами написать подобную функцию, взяв за основу этот код,
и сделав выборку нужный строки из массива.
Ну или заказать готовое решение.

А вопрос то актуальный. Дополнив функцию этой возможностью, её функционал стал бы гораздо качественне.

Можно с помощью Вашей функции взять только определенные строки, например со 2 по 20

Уберите строку Option Explicit - тогда не будет выскакивать ошибка Variable not defined

Пишет Variable not defined, указывая на binaryStream. Странно, ведь там все так же. :(

Mix, используйте эту функцию с третьим параметром "utf-8noBOM"

Добрый вечер!
Делаю по второму примеру, файл сохраняется в кодировке ANSI. Подскажите, как изменить данный пример чтобы сохранялось в кодировке utf-8 без BOM?

Это мое первое общение с VBA :)

Можно, конечно, и номер строки задать, откуда будут вставляться данные, - но код будет намного сложнее.
Алгоритм:
1) считываем весь текст из файла
2) разбиваем его на 2 части (по заданному номеру строки
3) формируем новый текст: 1-я часть + вставляемый текст + 2-я часть
4) записываем результат в тот же файл

Насчёт XML: очень не рекомендую использовать такой метод для XML, очень вероятны ошибки.
Там проще использовать объектную модель XML, программно добавляя новые узлы.

Очень интересна функция Добавление в текстовый файл из переменной, но так как я только начала изучать VBA, непонятно можно ли указать номер строки (в середине текста) начиная с которой начать добавление строк. И можно ли использовать эту функцию для добавления xml файл?

Здравствуйте! Подскажите пожалуйста, какой код надо написать, чтобы работал такой макрос: по нажатию кнопки выбирать папку, в которой есть текстовые файлы. В книгу вставляются листы с названиями от имени файлов в этой папке и в эти листы вводятся данные из этих файлов. Файлы содержат разную информацию: матрица, фамилии и дата рождения и т.д. Спасибо.

Anddre - если заменить "ReadTXTfile" на "txt",
то тогда функция будет всегда возвращать пустое значение. Любая Ф-я почти всегда должна содержать оператор присвоения значения переменной с именем самой функции.

Наконец я нашел решение! Спасибо огромное!
В моем случае, при сохранении TXTфайла с разделителями табуляции, нужно было записать первым пустой столбец, но любимый EXCEL сносил его и записывал файл таким образом что все столбцы смещались влево на одну позицию. запись Cells(1,1) = chr(09) приводила к возникновению цепочки сиволов кавычки-табуляция-кавычки в начале файла.
Пришлось прописывать Cells(1,1) = "?" (покрайней мере его видно в тексте), и тогда структура вроде сохранялась. Но система под которую этот файлик готовился могла на такое "нововведение" заругаться.
Как же я обрадовался когда удалось удалить из первой позиции аккруратно вырезать этот "?" и перезаписать файл в чистом виде.
Еще раз спасибо.

Спасибо за ресурс! Очень полезный. У меня несколько вопросов:

1) OpenTextFile(filename, 1, True)
второй и третий параметр этой функции что означают?
(а то редактор не выводит всплывающую подсказку)

2) Можно ли как-то считать только вторую строку текстового файла или записать во вторую строку?

3) При выведении значения в ячейку с помощью ReadTXTfile, в конце строки вместо переноса у меня стоит квадратик (нераспознанный знак), этого как-то можно избежать?

Заменить-то можно, но зачем?
Тогда придётся писать в коде дополнительную строку ReadTXTfile = txt
чтобы функция возвратила считанный из файла текст.

А так, как сейчас, всё работает без лишних строк.
(Мы намеренно записываем текст именно в ReadTXTfile, а не в какую-то текстовую переменную, поскольку функция должна возвратить загруженный текст)

макрос удалит на листе все строки, в которых содержится искомый текст:

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

Расширенная версия этого макроса - с использованием UserForm для ввода искомого значения



Ещё один вариант кода, позволяющего выполнять поиск (с последующим удалением или скрытием строк) сразу по нескольким условиям:

Комментарии

Относительно вопроса от 9 Сен 2011 - 20:12. (пишет тот же гость)
М.б. это происходит потому что мы назначаем массив с данными которые описываем функцией array, а соотв другой массив, который и нужно удалить он не видит.

Пробую использовать простую функцию циклическую, работает только при одном условии!! При нескольких уже нет, почему так происходит, подскажите, пжта, как можно решить эту проблему.

Добрый день!
Вы знаете, пробовал и в одном месте убрать NOT, и во всех где оно стоит, но ничего не получается. Подскажите, пжта, что делаю неправильно? Цель - удалить строки, в которых НЕ содержится текст. СпасибО!

Это на 26 комментарий замечание.

Почему-то если значений для исключения больше одного, то удаляет все строки.

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

Много условий можно записать в таком виде:

Проблема в том, что я не знаю, как в данном макросе сделать удобным ввод нескольких условий (а то давно бы реализовал)

Вариантов тут несколько, но они все недостаточно удобны:

1) писать все условия в коде - в принципе неправильно

2) вводить условия через форму ввода - можно, но там надо либо делать много полей (а это куча кода), либо одно большое поле, но тогда не будет видно, где заканчивается предыдущее условие, и начинается следующее (если текст условий не влазит в форму по длине в одну строку)
Да ещё и специально сохранять условия требуется - чтобы при следующем запуске макроса их снова не вводить.

3) загружать список условий с листа - но придётся где-то в макросе прописывать код, с какого листа скаких ячеек брать данные

4) текстовый файл со списком условий - тоже не совсем удобно может быть

Одной строчкой все условия у меня не влезают, excel начинает ругаться. Я их разбил но незнаю как их объединит, чтобы макрос по очереди все условия отрабатывал?
Спасибо

Sub УдалениеСтрокПоНесколькимУсловиям()
Dim ra As Range, delra As Range
Application.ScreenUpdating = False ' отключаем обновление экрана

' ищем и удаляем строки, содержащие заданный текст
' (можно указать сколько угодно значений, и использовать подстановочные знаки)
УдалятьСтрокиСТекстом = Array("Наименование *", "Количество", _
"текст?", "цен*сти", "*78*")
УдалятьСтрокиСТекстом = Array("Наименование *", "Количество", _
"текст?", "цен*сти", "*78*")
УдалятьСтрокиСТекстом = Array("Наименование *", "Количество", _
"текст?", "цен*сти", "*78*")

Пустые строки и столбцы могут быть головной болью в таблицах во многих случаях. Стандартные функции сортировки, фильтрации, подведения итогов, создания сводных таблиц и т.д. воспринимают пустые строки и столбцы как разрыв таблицы, не подхватывая данные, расположенные за ними далее. Если таких разрывов много, то удалять их вручную может оказаться весьма затратно, а удалить сразу всех "оптом", используя фильтрацию не получится, т.к. фильтр тоже будет «спотыкаться» на разрывах.

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

Способ 1. Поиск пустых ячеек

Это, может, и не самый удобный, но точно самый простой способ вполне достойный упоминания.

Предположим, что мы имеем дело вот с такой таблицей, содержащей внутри множество пустых строк и столбцов (для наглядности выделены цветом):

Исходные данные

Допустим, мы уверены, что в первом столбце нашей таблицы (колонка B) всегда обязательно присутствует название какого-либо города. Тогда пустые ячейки в этой колонке будут признаком ненужных пустых строк. Чтобы быстро их все удалить делаем следующее:

  1. Выделяем диапазон с городами (B2:B26)
  2. Нажимаем клавишу F5 и затем кнопку Выделить (Go to Special) или выбираем на вкладке Главная - Найти и выделить - Выделить группу ячеек (Home - Find&Select - Go to special) .
  3. В открывшемся окне выбираем опцию Пустые ячейки (Blanks) и жмём ОК – должны выделиться все пустые ячейки в первом столбце нашей таблицы.
  4. Теперь выбираем на вкладке Главная команду Удалить - Удалить строки с листа (Delete - Delete rows) или жмём сочетание клавиш Ctrl + минус - и наша задача решена.

Само-собой, от пустых столбцов можно избавиться совершенно аналогично, взяв за основу шапку таблицы.

Способ 2. Поиск незаполненных строк

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

Взгляните, например, на следующую таблицу - как раз такой случай:

Исходные данные с пустыми ячейками

Здесь подход будет чуть похитрее:

    Введём в ячейку A2 функцию СЧЁТЗ (COUNTA) , которая вычислит количество заполненных ячеек в строке правее и скопируем эту формулу вниз на всю таблицу:

Считаем количество заполненных ячеек

К сожалению, со столбцами такой трюк уже не проделать – фильтровать по столбцам Excel пока не научился.

Способ 3. Макрос удаления всех пустых строк и столбцов на листе

Для автоматизации подобной задачи можно использовать и простой макрос. Нажмите сочетание клавиш Alt + F11 или выберите на вкладке Разработчик - Visual Basic (Developer - Visual Basic Editor) . Если вкладки Разработчик не видно, то можно включить ее через Файл - Параметры - Настройка ленты (File - Options - Customize Ribbon) .

В открывшемся окне редактора Visual Basic выберите команду меню Insert - Module и в появившийся пустой модуль скопируйте и вставьте следующие строки:

Закройте редактор и вернитесь в Excel.

Теперь нажмите сочетание Alt + F8 или кнопку Макросы на вкладке Разработчик. В открывшемся окне будут перечислены все доступные вам в данный момент для запуска макросы, в том числе только что созданный макрос DeleteEmpty. Выберите его и нажмите кнопку Выполнить (Run) - все пустые строки и столбцы на листе будут мгновенно удалены.

Способ 4. Запрос Power Query

Ещё один способ решить нашу задачу и весьма частый сценарий - это удаление пустых строк и столбцов в Power Query.

Сначала давайте загрузим нашу таблицу в редактор запросов Power Query. Можно конвертировать её в динамическую "умную" сочетанием клавиш Ctrl+T или же просто выделить наш диапазон данных и дать ему имя (например Данные) в строке формул, преобразовав в именованный:

Присваиваем имя диапазону данных

Теперь используем команду Данные - Получить данные - Из таблицы/диапазона (Data - Get Data - From table/range) и грузим всё в Power Query:

Загруженные в Power Query данные

Дальше всё просто:

  1. Удаляем пустые строки командой Главная - Сократить строки - Удалить строки - Удалить пустые строки (Home - Remove Rows - Remove empty rows).
  2. Щёлкаем правой кнопкой мыши по заголовку первого столбца Город и выбираем в контекстном меню команду Отменить свёртывание других столбцов (Unpivot Other Columns). Наша таблица будет, как это технически правильно называется, нормализована - преобразована в три столбца: город, месяц и значение с пересечения города и месяца из исходной таблицы. Особенность этой операции в Power Query в том, что она пропускает в исходных данных пустые ячейки, что нам и требуется:

Читайте также: