NAME(File) или File

ОАР>> А вот {PROP:Name} прекрасно возвращает текущее имя файла.

VS> Но вот у {PROP:Name} есть другая проблема (по крайней мере была на C5
VS> и ранних релизах C55) — инициализировать {PROP:Name} нужно перед
VS> каждой «глобальной» операцией типа OPEN/CREATE/BUILD etc
VS> Так что пользовать {PROP:Name} нужно тоже с осторожностью.

Да тут надо просто понимать, как этот механизм работает! А все довольно просто. Как всегда — дело в трейдовости файлов и в потоках, в которых эти файлы работают.

Для файлов с аттрибутом THREAD:
1. У файла ЯВНО НЕ задано имя через аттрибут NAME
ИЛИ задана константа:
MyFile FILE…,THREAD
или
MyFile FILE…,NAME(‘C:MyFile.tps’),THREAD

В этом случае, ПОСЛЕ ВХОДА в каждый новый поток, имена этих файлов ВСЕГДА будут сбрасываться в их исходное значение, т.е. «MyFile» или «C:MyFile.tps».

В ПРЕДЕЛАХ ОДНОГО потока имена таким файлам СПОКОЙНО можно менять через {PROP:Name} и дальше В ЭТОМ потоке эти имена самостоятельно уже НЕ ИЗМЕНЯТСЯ.

Также следует иметь в виду, что если имя такого файла было изменено через {PROP:Name} и был вызван новый поток, где используется этот файл, то после возврата из нового потока имя файла в данном потоке НЕ ИЗМЕНИТСЯ.

!!! Для нетрейдового файла такое изменение имени будет действительным для ВСЕЙ программы, в ЛЮБОМ потоке.

2. у файла, в качестве параметра аттрибута NAME задана переменная с аттрибутом THREAD:
MyFileName STRING(260),THREAD
MyFile FILE…,NAME(MyFileName),THREAD

Все работает абсолютно аналогично первому случаю за исключением того, что в новом потоке имя файла будет взято из переменной MyFileName, присвоенное ей В ЭТОМ-ЖЕ ПОТОКЕ.

3. у файла, в качестве параметра аттрибута NAME задана переменная без аттрибута THREAD:
MyFileName STRING(260)
MyFile FILE…,NAME(MyFileName),THREAD

Аналогично первому случаю, ТОЛЬКО в новом потоке имя файла будет взято из переменной MyFileName, присвоенное ей последний раз в ЛЮБОМ ПОТОКЕ.

Следует ОСОБО подчеркнуть — для трейдовых файлов, в пределах одного потока, изменение имени через свойство {PROP:Name} ОТМЕНЯЕТ возможность изменение
этого имени через переменную, заданную в NAME!!! Т.е., если трейдовый файл описан с переменной в аттрибуте NAME, то первое-же изменение его имени через {PROP:Name}
убивает указатель на переменную и дальше, в данном потоке, изменить имя этого файла можно будет ТОЛЬКО через то-же свойство {PROP:Name}!!!

Для обычных нетрейдовых файлов это будет действительно на протяжении выполнения ВСЕЙ программы.

Вот именно для такого случая и следует с осторожностью относится к изменению имени через свойство {PROP:Name}.

Что-же касается определения имени файла, то я больше предпочитаю использовать именно {PROP:Name}. Как я уже писал, в ПРЕДЕЛАХ одного потока это свойство ВСЕГДА возвращает РЕ АЛЬНОЕ имя файла. А оператор NAME() возвращает реальное имя файла
ТОЛЬКО пока файл открыт!

Простейший тест:

TFile  FILE,DRIVER('TOPSPEED'),CREATE
...

- message(Name(TFile))      ! вернет "TFILE"
- message(TFile{PROP:Name}) ! вернет "TFILE"
  TFile{PROP:Name} = 'C:TEMPTFile.tps'
- message(Name(TFile))      ! вернет "TFILE"
- message(TFile{PROP:Name}) ! вернет "C:TEMPTFile.tps"
  OPEN(TFile)               ! или CREATE(TFile)
- message(Name(TFile))      ! вернет "C:TEMPTFile.tps"
- message(TFile{PROP:Name}) ! вернет "C:TEMPTFile.tps"
  CLOSE(TFile)
- message(Name(TFile))      ! вернет "TFILE"
- message(TFile{PROP:Name}) ! вернет "C:TEMPTFile.tps"

Еще хуже дела обстоят, если используется переменная для имени:
TFile FILE,DRIVER(‘TOPSPEED’),CREATE,NAME(GLO:TFileName)

  GLO:TFileName = 'D:DATATFile.tps'
- message(Name(TFile))      ! вернет "D:DATATFile.tps"
- message(TFile{PROP:Name}) ! вернет "D:DATATFile.tps"
  TFile{PROP:Name} = 'C:TEMPTFile.tps'
- message(Name(TFile))      ! вернет "D:DATATFile.tps" !!!
- message(TFile{PROP:Name}) ! вернет "C:TEMPTFile.tps"
  OPEN(TFile)               ! или CREATE(TFile)
- message(Name(TFile))      ! вернет "C:TEMPTFile.tps"
- message(TFile{PROP:Name}) ! вернет "C:TEMPTFile.tps"
  CLOSE(TFile)
- message(Name(TFile))      ! вернет "D:DATATFile.tps" !!!
- message(TFile{PROP:Name}) ! вернет "C:TEMPTFile.tps"

!!! Не правда-ли — по крайней мере странно — файл на самом деле создан и лежит в «C:TEMPTFile.tps», а оператор NAME() продолжает нас уверять, что файл создан и лежит совсем в другом месте, а именно в «D:DATATFile.tps». Хотя буквально недавно, до закрытия файла, этот-же оператор вполне правильно определял месторасположение этого файла. Во истину — женская непостоянность!!!

Т.е. можно сделать очевидный вывод, что оператор NAME() для НЕОТКРЫТЫХ файлов ВСЕГДА возвращает значение имени из ЗАГОЛОВКА файла. А это — НЕПРАВИЛЬНО!!!
Дело в том, что первое ЛЮБОЕ действие с файлом приводит к созданию управляющей структуры файла и в дальнейшем (для трейдовых файлов — в пределах текущего трейда,
а для нетрейдовых файлов — в рамках всей программы) вся информация по этому файлу читается/пишеться через эту самую управляющую структуру!
А вот для открытых файлов оператор NAME() обращается уже непосредственно к этой самой управляющей структуре.

Опять-же, Агеев и Чушкин, может укажете разработчикам из SV на это расхождение как между методами работы свойства {PROP:Name} и оператора NAME() (которые, по идее, должны ВСЕГДА возвращать одно и то-же), так и на очевидную ошибку в работе оператора NAME() с неоткрытыми файлами?

Хотя, возможно я и не совсем прав?
Все таки иногда полезно, вероятно, получить для неоткрытого файла не его реальное текущее имя а значение переменной из его аттрибута NAME()?

Но, в таком случае, надо ОЧЕНЬ ЧЕТКО представлять себе логику работы как NAME() так и {PROP:Name}. А вот это как раз и не вполне четко прописано в доке.