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}.
А вот это как раз и не вполне четко прописано в доке.