1

Тема: VBS Запись в текстовый файл строки с произвольным номером

Для одного небольшого проекта была сделана такая функция:


Function TXTwrite(LineN, strTP) ' Номер строки и сама строка для записи
	On Error Resume Next
	Set WshShell = CreateObject("WScript.Shell")
	path = WshShell.CurrentDirectory + "\"
	Set objFS = CreateObject("Scripting.FileSystemObject")
	writDO=""
	writPOS=""
	Set objFS = CreateObject("Scripting.FileSystemObject")
	Set objTS = objFS.OpenTextFile(Path+"flm.tmp", 1) ' Файл flm.tmp содержит набор записей с разделителем |
	ks=0
	LineN=CLng(LineN)
	Do Until objTS.AtEndOfStream
	ks=ks+1
	if ks<LineN then writDO=writDO+objTS.Readline &  VbCrLf
		if ks=LineN then 
		Str=objTS.ReadLine
		strArr=Split(str,"|",-1,1)
		writITM=strArr(0)&"|"&strArr(1)&"|"&strArr(2)&"|"
		End If
	if ks>LineN then writPOS=writPOS+objTS.Readline &  VbCrLf
	loop
	objTS.close
	Set objTS = objFS.OpenTextFile(Path+"flm.tmp", 2)
	objTS.Write writDO &Left(writITM,len(writITM)-1) &"|" &strTP &  VbCrLf & writPOS ' Содержимое файла ДО искомой строки + нужная нам строка + содержимое файла после
	objTS.close
	TXTwrite=0
End Function

Если работать с файлом на 20-30 строк то все красиво. Но тут понадобилось делать тоже самое с файлом в 12000 строк и стало все совсем медленно.
Вопрос: как еще можно решить подобную задачу, чтобы работало пошустрее

Автоматизирую торговлю. Не 1С

2

Re: VBS Запись в текстовый файл строки с произвольным номером

1. arrLines = Split(.ReadAll(), vbCrLf); arrLines(N) = "bla-bla-bla"; Write(Join(arrLines, vbCrLf)).
2. При очень большой размере — пытаться работать с файлом, как с базой данных.

По Вашему коду. Применять это:

    On Error Resume Next

бездумно — не стоит совершенно.

Это:

    Set WshShell = CreateObject("WScript.Shell")
    path = WshShell.CurrentDirectory + "\"

в данном случае совершенно лишнее. Работа и так будет идти с текущим каталогом.

3

Re: VBS Запись в текстовый файл строки с произвольным номером

Mat Skywalker пишет:

как еще можно решить подобную задачу, чтобы работало пошустрее

Упростите алгоритм - у Вас три избыточных сравнения, что может привести как к замедлению работы скрипта, так и к ошибкам. Избавьтесь от копирования строк - это очень трудоемкий процесс. Если все данные все-таки необходимы, то храните данные в массиве.

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


Function TXTwrite2(N)
	On Error Resume Next
	Set fso = CreateObject("Scripting.FileSystemObject")
	Set f = fso.OpenTextFile(FileName, 1)
	L = 0
	Do Until f.AtEndOfStream
		S = f.ReadLine
		L = L + 1

		' строка найдена ...
		If N = L Then
			' ... что-то сделать с ней ...
			S = <...>
		End If
		' ... и тут же вывести на консоль
		WScript.Echo S
	Loop
	f.Close
End Function

Второй вариант (данные сохраняются и пишутся в тот же файл)


Function TXTwrite3(N)
	On Error Resume Next

	' массив хранения всех строк входного файла
	Dim result()
	' текущий размер массива
	M = 0
	' величина на которую увеличиваем массив
	Incr = 100

	Set fso = CreateObject("Scripting.FileSystemObject")
	Set f = fso.OpenTextFile(FileName, 1)
	L = 0
	' строки отсчитываем с нуля
	N = N - 1
	Do Until f.AtEndOfStream
		S = f.ReadLine
		' строка найдена ...
		If N = L Then
			' ... что-то сделать с ней ...
			S = <...>
		End If
		' убедиться, что емкости массива достаточно для хранения всех строк
		If L Mod Incr = 0 Then
			M = M + Incr
			ReDim Preserve result(M)
		End If
		' сохранить все строки во временном массиве
		result(L) = S
		L = L + 1
	Loop
	f.Close

	' сохранить все строки (оригинальные и измененные)
	Set f = fso.OpenTextFile(FileName, 2)
	For I = 0 To L - 1
		f.WriteLine result(I)
	Next
	f.Close
End Function

В обоих случаях файл размером в 20тыс строк был прочитан и изменен за 2-3 секунды

( 2 * b ) || ! ( 2 * b )

4

Re: VBS Запись в текстовый файл строки с произвольным номером

Хмм… «ReDim Preserve …» — очень затратная операция.

5

Re: VBS Запись в текстовый файл строки с произвольным номером

Возможно. Но опыт говорит о противоположном. Это менее затратная операция чем конкатенация строк.

( 2 * b ) || ! ( 2 * b )