ник: Explorer
при сокращении Ф.И.О. до инициалов или плюсы (+) неявного приведения типа данных
иногда, например при подготовке источника записей для отчета, требуется объединять значения
из разных полей таблицы или запроса в одну строку. Самый распространенный случай,
c которым сталкивался, вероятно, каждый - необходимость объединять строковые (String) данные вида
Фамилия | Имя | Отчество
---------+-------------+------------
Иванов | Василий | Львович
Масалиев | Абсамат |
|
в одну строку, разделяя (например) значения Фамилии Имени и Отчества пробелом. В этом нет ничего сложного -
благо функция "&" позволяет легко "склеивать" такие значения, выполняя так называемую конкатенацию:
***********************************
1) [Фамилия] & " " & [Имя] & " " & [Отчество]
Иванов Василий Львович
***********************************
|
Могут встречаться и более экзотические случаи, когда в результат такого "склеивания" нужно включить
не просто пробелы, а дополнительные символы или разделители - например точку после инициалов:
***********************************
2) [Фамилия] & " " & (UCase(Left([Имя];1)) & "." & (UCase(Left([Отчество];1))& "."
Иванов В.Л.
***********************************
|
или, как более экзотический вариант, формирование номера некоторого документа по определенному шаблону.
Например
"Договор № ######-YY (***)"
казалось бы и этот случай также не вызовет сложностей - просто вставляем
нужные символы в нужное место - достаточно написать в запросе что-то вроде:
***********************************
3) "Договор № " & [КодДоговора] & "-" & (Format([ДатаЗаключения];"yy") & " (" & [ВерсияДоговора]& ")"
Договор № 780-07 (32)
***********************************
|
но что делать, если некоторые записи таблицы-источника не содержат данных для запроса - например
если у сотрудника нет отчества или у договора нет версии и соответствующее поле таблицы не заполнено.
При использовании описанных выше приемов c конкатенацией и "слиянием" значений получится что-то вроде:
1)
"Масалиев Абсамат "
или
2)
"Масалиев А.."
или
3)
"Договор № 780-07 ()"
в одном случае (1; 2) появится лишняя точка (или пробел) при отсутствии значения в поле "Отчество",
в другом (3) лишние открывающая и закрывающая скобки если нет номера версии договора "ВерсияДоговора".
допустим, в первом случае (1), лишний пробел можно убрать функцией TRIM (RTrim; LTrim), и это совершенно несложно
1) Trim([Фамилия] & " " & [Имя] & " " & [Отчество])
|
но для того, чтобы убать точку или скобки,как в примере (2; 3), пришлось бы использовать громоздкие конструкции с функцией IIF
проверяя наличие значения в поле на Is Not Null, подставляя, соответственно, точку после отчества, или скобки к номеру версии
2) IIF([Отчество]Is Not Null;([Фамилия] & " " & (UCase(Left([Имя];1)) & "." & (UCase(Left([Отчество];1))& ".");([Фамилия] & " " & (UCase(Left([Имя];1)) & "."))
|
3) про скобки в случае с номером договора даже и писать не хочется - тем более, что это еще не самый тяжелый случай,
иногда в отчетах нужно формировать строки и посложнее - с датой договора, фамилиями представителей сторон и проч.
как можно упростить такой хитрый запрос? очень просто - вспомнить правило
х + Null = Null и использовать
операцию сложения вместо функции конкатенации, там, где значение некоторго поля может быть равно Null
таким образом выражение вида [
Отчество] + "." вернет Null (или строку нулевой длины), если значение поля [Отчество] = Null и в прочих случаях аналогично:
1) [Фамилия] & " " & [Имя] & (" " + [Отчество]) = "Масалиев Абсамат"
т.е. Null вместо лишнего пробела перед отсутствующим отчеством
|
2) [Фамилия] & " " & UCase(Left([Имя];1)) & "." & (UCase(Left([Отчество];1)) + ".") = "Масалиев А."
т.е. Null вместо лишней точки после отсутствующего инициала
|
3) "Договор № " & [КодДоговора] & "-" & Format([ДатаДоговора];"yy") & (" (" + [ВерсияДоговора] + ")") = "Договор № 780-07"
т.е. Null вместо лишних скобок и пробела
|
ЗЫ
напомню про подводные камни :)
если в "сливаемых" полях таблицы будут содержаться числовые значения (цифры), то такое неявное преобразование может привести к неожиданным сюрпризам
например строковые значения могут быть истолкованы как числовые, в этом случае оперция сложения может быть выполнена буквально