Добрый день коллеги, при загрузке раздела дважды возникает ошибка

 

Заголовок для подписи "SymptomsFieldContainer1" не был найден.

Невозможно найти колонку по конфигурации: "{"layout":{"colSpan":24,"rowSpan":1,"column":0,"row":2},"name":"SymptomsFieldContainer1"}" .

 

SymptomsFieldContainer1 это поле типа контейнер для того, чтобы было реализовано новое поле по типу "Описание".

Оно было добавлено в замещающей странице CasePage

{
	"operation": "insert",
	"name": "SymptomsFieldContainer1",
	"values": {
		"layout": {
			"column": 0,
			"row": 2,
			"colSpan": 24,
			"rowSpan": 1,
			"layoutName":"Header"
		},
		"wrapClass": [
			"control-width-15 control-left solution-field-container"
		],
		"itemType": 7,
		"items": []
	},
	"parentName": "CaseInformation_gridLayout",
	"propertyName": "items",
},

Методом проб и ошибок выяснилось, что ошибка возникает дважды на двух старых схемах

Изображение удалено.

При этом CasePage является родительской для всех Page в данном разделе.

Ошибка не возникает на других двух схемах, но при этом видимо конфликтует с старыми.

Нравится

2 комментария

Добрый день,

 

Попробовал добавить этот контейнер на демку - никаких ошибок нет. Кроме того, Вы уверены, что у страниц редактирования из Вашего скриншота родитель CasePage, а не BaseModulePageV2 (стандартная для типизированных страниц). Или была дополнительная кастомизация и родитель у страниц менялся? Если так, то можно получить полный код одной из страниц редактирования, открытие которой возвращает ошибку и еще как она влияет на работу сайта помимо того, что контейнер не отображается?

Добавить комментарий

Oleg Drobina,

Спасибо за ваш ответ, визуально проблем выявлено не было, но само наличие ошибки смущает.

Родительская страница у всех CasePage, но при реализации кастомного пакета, этот CasePage был замещен и в нём реализован новый контейнер, прикрепляю код данной страницы

define("CasePage", [], function() {
	return {
		entitySchemaName: "Case",
		attributes: {},
		modules: /**SCHEMA_MODULES*/{}/**SCHEMA_MODULES*/,
		details: /**SCHEMA_DETAILS*/{
			"FileDetailV2fe3b2d92": {
				"schemaName": "FileDetailV2",
				"entitySchemaName": "CaseFile",
				"filter": {
					"detailColumn": "Case",
					"masterColumn": "Id"
				}
			},
			"KnowledgeBaseInCaseDetailfca68878": {
				"schemaName": "KnowledgeBaseInCaseDetail",
				"entitySchemaName": "KnowledgeBaseInCase",
				"filter": {
					"detailColumn": "Case",
					"masterColumn": "Id"
				}
			},
			"VisaDetailV218d4bda2": {
				"schemaName": "VisaDetailV2",
				"entitySchemaName": "ITdsCaseVisa",
				"filter": {
					"masterColumn": "Id",
					"detailColumn": "ITdsCase"
				}
			}
		}/**SCHEMA_DETAILS*/,
		businessRules: /**SCHEMA_BUSINESS_RULES*/{}/**SCHEMA_BUSINESS_RULES*/,
		methods: {},
		diff: /**SCHEMA_DIFF*/[
			{
				"operation": "insert",
				"name": "ReclassificationButton",
				"values": {
					"itemType": 5,
					"caption": {
						"bindTo": "Resources.Strings.ReclassificationButtonCaption"
					},
					"click": {
						"bindTo": "onReclassificationButtonClick"
					},
					"enabled": true,
					"visible": true,
					"style": "red",
					"layout": {
						"column": 1,
						"row": 6,
						"colSpan": 1
					}
				},
				"parentName": "LeftContainer",
				"propertyName": "items",
				"index": 10
			},
			{
				"operation": "insert",
				"name": "TestButton1",
				"values": {
					"itemType": 5,
					"caption": "Test",
					"click": {
						"bindTo": "onTestButtonClick1"
					},
					"enabled": true,
					"visible": false,
					"style": "yellow",
					"layout": {
						"column": 1,
						"row": 6,
						"colSpan": 1
					}
				},
				"parentName": "LeftContainer",
				"propertyName": "items",
				"index": 11
			},
			{
				"operation": "insert",
				"name": "NegotiationButton1",
				"values": {
					"itemType": 5,
					"caption": {
						"bindTo": "Resources.Strings.NegotiateButtonCaption1"
					},
					"click": {
						"bindTo": "onNegotiationButtonClick1"
					},
					"enabled": {
						"bindTo": "isNegotiatorSet1"
					},
					"visible": {
						"bindTo": "isNegotiatorSet1"
					},
					"style": "green",
					"layout": {
						"column": 1,
						"row": 6,
						"colSpan": 1
					}
				},
				"parentName": "LeftContainer",
				"propertyName": "items",
				"index": 12
			},
			{
				"operation": "remove",
				"name": "Symptoms"
			},
			{
				"operation": "insert",
				"name": "SymptomsFieldContainer",
				"values": {
					"layout": {
						"column": 0,
						"row": 1,
						"colSpan": 24,
						"rowSpan": 1
					},
					"wrapClass": [
						"control-width-15 control-left solution-field-container"
					],
					"itemType": 7,
					"items": []
				},
				"parentName": "CaseInformation_gridLayout",
				"propertyName": "items",
			},
			{
				"operation": "insert",
				"name": "Symptoms",
				"values": {
					"itemType": 3,
					"dataValueType": 1,
					"contentType": 4,
					"value": {
						"bindTo": "Symptoms"
					},
					"markerValue": "Symptoms",
					"labelConfig": {
						"visible": false
					},
					"controlConfig": {
						"imageLoaded": {
							"bindTo": "onImageLoaded"
						},
						"imagePasted": {
							"bindTo": "onImagePasted"
						},
						"plainTextValue": {
							"bindTo": "NotHtmlNote"
						},
						"images": {
							"bindTo": "Images"
						},
						"plainTextMode": {
							"bindTo": "plainTextMode"
						}
					}
				},
				"parentName": "SymptomsFieldContainer",
				"propertyName": "items"
			},
			{
				"operation": "move",
				"name": "ESNTab",
				"parentName": "Tabs",
				"propertyName": "tabs"
			},
			{
				"operation": "move",
				"name": "TimelineTab",
				"parentName": "Tabs",
				"propertyName": "tabs",
				"index": 3
			},
			{
				"operation": "insert",
				"propertyName": "tabs",
				"parentName": "Tabs",
				"name": "Tabf1d4d2a9TabLabel",
				"values": {
					"caption": {
						"bindTo": "Resources.Strings.TabVisaCaption"
					},
					"items": []
				}
			},
			{
				"operation": "insert",
				"propertyName": "items",
				"parentName": "Tabf1d4d2a9TabLabel",
				"name": "VisaDetailV218d4bda2",
				"values": {
					"itemType": 2,
					"markerValue": "added-detail"
				}
			}
		]/**SCHEMA_DIFF*/
	};
});

 

Показать все комментарии

Можно ли как-то переименовать название объекта таблицы (точнее заголовок). При изменении в объекте сама ORM не переименовывает таблицу в базе данных, а если руками переименовать таблицу а потом объект - тогда выдает ошибку "Ошибка сохранения: ORA-00942: table or view does not exist".

И да, база данных Oracle

Нравится

3 комментария

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

Именно заголовок сменился нормально, объект опубликовался:

Зверев Александр,

я как раз ошибся, мне нужно "название" а не "заголовок" сменить. Но Ваше разьяснее как раз подошло, спасибо. Как вывод - лучше не лезть. А если лесть то по Вашему описанию.

Потом посмотрел ещё раз, для наследуемых объектов даже и заголовок нужно через метаданные. А для названия действительно без крайней нужды лучше не трогать, разве что только если объект Вами же сделан. А то вдруг переименуете стандартный и вдруг придёт на него обновление...

Показать все комментарии

Добрый день!
При разработке на препроде возникла необходимость переименовать базовые разделы, и само собой изменена некая логика этих базовых разделов.
Так вот проблема в чем, при переносе этих всех изменений заголовки разделов в меню разделов, данные заголовки не меняются.
Собственно вопрос в том, как изменить заголовки раздела не через мастер и без использования esq запросов? Перепробовал менять все caption, но так и не нашел решения данной проблемы.
Или же вариант решения только тем, что придется добавить sql-скрипт к пакету при установке на проде?

Нравится

2 комментария

Михаил, здравствуйте!

Лучшим вариантом будет это:

- создать SQL скрипт, который «проайпдейтит» необходимые локализируемые строки;

Например:

Название кнопки берется из поля ActionKindCaption таблицы SysModuleEdit.

Предположим раздел "Контрагенты" имеет несколько страниц редактирования. Тогда страницы можно определить следующим запросом:

select * from SysModuleEdit
where SysModuleEntityId = (select Id from SysModuleEntity
where SysEntitySchemaUId = (select UID from SysSchema where Name = 'Account' and ExtendParent = 0))

Далее запросом update необходимо задать новое значение в колонку ActionKindCaption для требуемой записи.

- в пакете разработке добавить этот скрипт во вкладке «SQL сценарии» и указать тип установки «После сохранения пакета» (чтобы скрипт запустился после установке пакета на другую среду) + создать привязку скрипта к пакету, чтобы его можно было переносить на другую среду.

Другой пока возможности нет.
Приятной работы!

Дмитрий, благодарю.

Показать все комментарии

Доброго времени суток.
При выборе значений из справочников во всех разделах к названию приписывается “undefined”, к примеру:
!
В чем может быть проблема?

Нравится

4 комментария

Здравствуйте!

Предоставьте, пожалуйста, результат выполнения запроса:

select ModuleHeader from SysModuleEntity
join SysSchema
on SysSchema.Uid = SysModuleEntity.SysEntitySchemaUId
join SysModule
on SysModule.SysModuleEntityId = SysModuleEntity.Id
where SysSchema.Name = 'Contact'
Список: Контакты

Здравствуйте!

Данное поведение актуально для версии приложения 7.9.1.
В ближайших релизах оно будет устранено, а для указанной версии будет выпущен пакет исправлений.

Эта же ошибка проявляется в 7.11.1.

ВСЕ лукапы отображаются с "undefined" http://prntscr.com/hd8fxz.

Подскажите, как бороться?

Показать все комментарии
Предлагаю создать три функции SectionHeader, ListHeader и PageHeader, которые разработчики могут самостоятельно перееопределять, тем самым легко динамически задавая заголовок раздела, списка или карточки.Сейчас заголовок занимает очень много места, которое используется не самым эффективным образом. А можно там изображать название контрагента, имя контакта, номер счёта и т.п. Чтобы реализовать это в настоящий момент, приходится пописать кода (http://www.community.terrasoft.ua/forum/topic/12370), но результат того стоит (см пример в приложении). C помощью функций можно существенно облегчить эту задачу.
1 комментарий

Здравствуйте, Владимир!

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

Показать все комментарии

Можно ли изменять заголовок страницы редактирования в bpm'online 7.5 в зависимости от данных на странице (например, вместо "Контрагент" отображать строку, состоящую из типа и названия контрагента)?

Нравится

6 комментариев

Владимир, добрый день!

Для реализации необходимо , чтобы на странице присутствовал ChangeHeaderCaption иначе заголовок не будет меняться.

Примерный алгоритм:

Используя замещенную страницу добавьте на onEntityInitialized или на любом другом init новый мэсседж :

messages:  {
 
"ChangeHeaderCaption": {
					mode: Terrasoft.MessageMode.PTP,
					direction: Terrasoft.MessageDirectionType.PUBLISH
				},
}

Затем добавить новый метод, в котором будет присутствовать следующая строка:

this.sandbox.publish("ChangeHeaderCaption", { caption: "добавить свое условие" } )

Как наглядный пример, можете ознакомиться с initMainHeaderCaption (BaseSectionV2) как там реализован ChangeHeaderCaption.

Спасибо!

Частично получилось.

Добавил messages:

messages: {
	"ChangeHeaderCaption": {
		mode: Terrasoft.MessageMode.PTP,
		direction: Terrasoft.MessageDirectionType.PUBLISH
	}
}

Переопределил:

onEntityInitialized: function() {
	this.callParent(arguments);
	this.updateSectionHeader();
}

Добавил функцию:

updateSectionHeader: function() {
	var caption = "";
	var type = this.get("Type");
	var ContactName = this.get("Name");
	if (type) {
		if (ContactName) {
			caption = ContactName + "( " + type.displayValue+ " )";
		} else {
			caption = "New " + type.displayValue;
		}
	} else {
		caption = this.entitySchema.caption;
	}
	this.sandbox.publish("ChangeHeaderCaption", {
		caption: caption,
		dataViews: new Terrasoft.Collection(),
		moduleName: this.name
	});
}

Что работает:
1. При добавлении записи
2. При открытии записи на редактирование

Что не работает:
1. Если закрывается запись, то заголовок остаётся (надо, чтобы менялся на стандартный для раздела)
2. Если закрыть полосу списка, то при открытой записи заголовок меняется на стандартный для раздела (надо, чтобы оставался)
3. Если запись сохранить, но не закрывать, то заголовок не меняется (нужно менять при сохранении).

Очевидно, что на onEntityInitialized недостаточно вызова функции. Какие еще методы надо переопределить, чтобы отрабатывали три неработающие вещи?

И дополнительный вопрос:

Как отличить, открыта ли карточка (при незакрытом списке) или закрыта (и виден только реестр).
В первом случае нужно показывать заголовок карточки, во втором - заголовок реестра

Владимир, добрый день!

Сначала ответ на последний вопрос. В схеме BaseSectionV2 есть два атрибута: "IsCardVisible" и "IsSectionVisible", которые можно использовать для определения видимости карточки и раздела. Также базовый модуль карточки редактирования (CardModuleV2) содержит флаг isSeparateMode, который указывает на то, что карточка на странице отображается одна. Если значение этого флага равно false - это значит, что на странице кроме CardModuleV2 присутствует и SectionModuleV2 в виде вертикального реестра. Абсолютно такой же флаг есть и у SectionModuleV2.

Что касается публикации сообщения "ChangeHeaderCaption" - она происходит, кроме инициализации, в следующих случаях:

1) при закрытии вертикального реестра (метод onCloseSectionButtonClick схемы BaseSectionV2) - причина изменения заголовка в Вашем п.2;
2) при переходе в представление "Аналитика" и обратно.

Для реализации изменения заголовка (п.1 и п.3) Вам необходимо добавить публикацию данного сообщения (либо метода, который инициирует публикацию) при обработке нажатия кнопок "Сохранить" и "Закрыть" в карточке редактирования.

"Лабьяк Олег Игоревич" написал: В схеме BaseSectionV2 есть два атрибута: "IsCardVisible" и "IsSectionVisible"

1. А как можно в коде страницы получить значения этих атрибутов?
2. В код добавил метод onCloseSectionButtonClick, однако его вызова при закрытии списка не происходит
3. И какой метод вызывается при закрытии карточки редактирования?

Спасибо!

Владимир,

1) в коде страницы необходимо использовать this.get("IsSeparateMode"), по значению которого можно определить, присутствует ли на странице вертикальный реестр (если он скрыт, но его можно отобразить с помощью соответствующего действия, значения атрибута тоже будет false), либо нет (добавлена новая запись). Атрибуты "IsCardVisible" и "IsSectionVisible" доступны только в коде раздела.

2) Вы добавили метод в код карточки? Этот метод определён в BaseSectionV2, соответственно, вызывается из кода раздела.

3) При закрытии карточки редактирования (по кнопке "Закрыть") вызывается метод onCloseClick. Если с точки зрения модуля раздела - метод closeCard.

Вообще, Вашу задачу можно решить примерно так:

1) в карточке редактирования переопределяем метод getHeader, чтобы он возвращал необходимое Вам значение:

getHeader: function() {
	var caption = "";
	var type = this.get("Type");
	var contactName = this.get("Name");
	if (type) {
		caption += (contactName && (contactName + " ( " + type.displayValue + " )")) || ("New " + type.displayValue);
	} else {
		caption = this.entitySchema.caption;
	}
	return caption;
}

2) переопределяем метод initHeader, чтобы он выполнял обновление заголовка не только при добавлении новой записи:

initHeader: function() {
	var entityCaption = this.getHeader();
	this.sandbox.publish("InitDataViews", {caption: entityCaption});
	if (this.get("IsSeparateMode")) {
		this.initContextHelp();
	}
}

3) переопределяем метод onSaved, чтобы заголовок обновлялся при сохранении записи:

onSaved: function() {
	this.initHeader();
	this.callParent(arguments);
}

4) переходим в схему раздела и переопределяем в ней метод onCloseSectionButtonClick, чтобы обновление заголовка не выполнялось при скрытии вертикального реестра:

onCloseSectionButtonClick: function() {
	this.hideSection();
	this.removeSectionHistoryState();
	this.updateCardHeader();
}

5) наконец, переопределяем метод closeCard, обновляя заголовок после закрытия карточки редактирования:

closeCard: function() {
	this.callParent(arguments);
	this.updateSectionHeader();
}
Показать все комментарии
В bpm'online 7.5 можно поменять в карточке формат поля на Title, но меняется только формат label'а. Было бы хорошо менять и формат отображения самих данных (например, больший размер и выделение bold'ом)
1 комментарий

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

Показать все комментарии

Перекопал все скрипты в террасофте, и Grep Search использовал, но так толком ничего и не нашел, с обычными полями понятно xxxControl.Caption = 'yyyy'; или xxxControl.DataField.Caption = 'yyyy';
А как можно обратиться подобным образом к пользовательскому полю и изменить его заголовок?

(P.S. Заменить пользовательские поля на фиксированные не предлагать, в моем случае нужно изменить именно пользовательское поле, и изменять динамически в зависимости от условий)

Нравится

2 комментария

Навскидку такой скрипт.

//пробежим по всем элементам окна
for(var i=0;i<Self.ComponentCount; ++i) {
    if (Self.Components(i).DataFieldName == 'INN') { //находим, нужное поле/поля (например по названию поля датасета, который привязан)
        Self.Components(i).Caption = 'Что-то другое';//ставим caption 
    }
}

Не проверял, не уверен, но быть может поможет.

"Сазанов Александр Владимирович" написал:

Навскидку такой скрипт.

//пробежим по всем элементам окна

for(var i=0;i<Self.ComponentCount; ++i) {

    if (Self.Components(i).DataFieldName == 'INN') { //находим, нужное поле/поля (например по названию поля датасета, который привязан)

        Self.Components(i).Caption = 'Что-то другое';//ставим caption

    }

}

Не проверял, не уверен, но быть может поможет.


Большое спасибо! Действительно работает, даже не догадался что можно просто перебрать все элементы окна)

Показать все комментарии

Стоит задача: Есть задача (активность в bpm), нужно послать письмо ответственному и автору какие поля были изменены. С отправлением письма разберусь, а как в bpm5 получить список всех полей сущности, и как по названию поля получить его заголовок. Думаю понятно объясню в коде

Entity CurrentEntity = this.Entity; //Текущая запись - задача
string[] arFieldsNames = ;//как получить в массив строк полей по сущности?
string[] arFieldsTitles = ;//как получить массив заголовков полей либо ниже, как по названию поля, получить его заголовок?
var emailBody = "Измененные значения:

"
;//тело для письма
for(var i=0;iarFieldsNames.Length;i++) {
        //Сравниваем старое и новое значение
        if (CurrentEntity.GetColumnOldValue(arFieldsNames[i]) != CurrentEntity.GetColumnValue(arFieldsNames[i])) {
                        var fieldTitle = ;//как получить сроку "Ответственный" по строке "Owner" или "OwnerId"?
                        emailBody += fieldTitle + ": " + CurrentEntity.GetColumnDisplayValue() + "

"
;//Записываем в тело письма
        }
}

Грубо говоря хотелось бы получить такое
Измененные значения:
Ответственный: Пользователь2
Состояние: В работе

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

Нравится

3 комментария

Хороший вопрос, поддерживаю.

Здравствуйте!
Доступ к колонкам можно получить так:

var columns = this.Entity.Schema.Columns; //коллекция колонок
//затем можно их перебрать
foreach (var column in columns)
{
	//своя логика
        //column.Caption - подпись колонки, например
}

Если делать в БП, то можно получить схему из элемента "Чтение данных" так:

var schema = ReadDataUserTask1.ResultEntity.Schema;

То что надо. Спасибо.

Показать все комментарии

Конечно это громко сказано, но в случае, если Вам необходимо изменить заголовки сервисов по всей системе, а именно заголовки датасетов, названия окон, элементов окон и т.п., то для этих нужд можно воспользоваться разработанной функцией (см. ниже). Как пример, допустим нам нужно изменить название раздела с "Контрагенты" на "Юр. лица", кроме того, необходимо внести эти изменения во все карточки, во все реестры и т.д.

function ReplaceCaption(FromCaption, ToCaption) {
 try {
  System.BeginProcessing();
  Log.Write(1, "Старт: " + (new Date()).toLocaleString());
  var ServiceCount = Services.InformationsCount;
  var LoadedCount = 0;
  var ChangedCount = 0;
 
  System.ProcessMessages();
  var RE = new RegExp(FromCaption, 'g');
  for (var i = 0; i ServiceCount; i++) {
   System.ProcessMessages();
   var Info = Services.Informations(i);
   var ServiceTypeCode = Info.ServiceTypeCode;
   var ToLoad = IsStringInArray(ServiceTypeCode, ['DBDataset', 'Window']);
   if (ToLoad) {
    try {
     if (Info.USI.substring(0, Info.USI.indexOf('\\')) == 'Call Centre') {
      continue;
     }
     var Service = GetSingleItemByCode(Info.USI);
    } catch(e) {
     continue;
    }
    LoadedCount++;
    // Изменяем заголовок самого сервиса
    Service.Caption = Service.Caption.replace(RE, ToCaption);
    if ((ServiceTypeCode == 'DBDataset') && (Assigned(Service.DataFields))) {
     var Count = Service.DataFields.Count;
     // Изменяем заголовки датафилдов
     for (var j = 0; j Count; j++) {
      var Item = Service.DataFields.Items(j);
      Item.Caption = Item.Caption.replace(RE, ToCaption);
     }
     Services.SaveItem(Service, sdoaSave);
     ChangedCount++;
    } else if ((ServiceTypeCode == 'Window') && (Service.ComponentCount > 0)) {
     if (Service.Name == 'wnd_Main') {
      // Отключить таймер
      var Timer = Service.ComponentsByName('Timer');
      Timer.IsEnabled = false;
     }
     if (Service.Name == 'wnd_CallCentreClient') {
      // Отключить таймер
      var Timer = Service.ComponentsByName('tmrRefreshCallList');
      Timer.IsEnabled = false;
     }
     var Count = Service.ComponentCount;
     // Изменяем заголовки контролов
     for (var j = 0; j Count; j++) {
      var Item = Service.Components(j);
      if (!IsEmptyValue(Item.Caption)) {      
       Item.Caption = Item.Caption.replace(RE, ToCaption);
      }
     }
     Services.SaveItem(Service, sdoaSave);
     ChangedCount++;
    }
   }
  }
 } finally {
  System.EndProcessing();
  Log.Write(1, "Финиш: " + (new Date()).toLocaleString());
 }
 Log.Write(1, "Всего сервисов: " + ServiceCount +
        " Рассмотрено сервисов: " + LoadedCount +
        " Изменено сервисов: " + ChangedCount);
}

function Main() {
        ReplaceCaption('Контрагенты', 'Юр. лица');
}

Параметры функции ReplaceCaption():
FromCaption - фраза, которую нужно найти и заменить
ToCaption - фраза, на которую нужно заменить

Небольшие рекомендации:
1. Перед использованием сделать ОБЯЗАТЕЛЬНО бекап, "дабы не было мучительно больно..."
2. При установке параметров функции нужно помнить, что функция ищет любые совпадения, т.е. если мы хотим заменить "Контрагент" на "Юр.лицо", то при обнаружении слова "Контрагенты" будет сделана некорректная замена на "Юр.лицоы". Поэтому запускать ее нужно сначала для самых длинных склонений, далее для множественного числа и т.д.

Пример: нужно заменить все упоминания "проектов" на "сделки". Для этого запускаем функцию поэтапно со следующими параметрами:
Проектами - Сделками
проектами - сделками
Проектов - Сделок
проектов - сделок
Проекты - Сделки
проекты - сделки
Проектом - Сделкой
проектом - сделкой
Проекта - Сделки
проекта - сделки
Проект - Сделка
проект - сделка

и т.д.

Как видите, приведенная функция не универсальна. Т.е. ее можно доработать, добавив дополнительные параметры замены (учет регистра символов, можно "прикрутить" какой-то алгоритм склонения слов и т.п.). Следовательно, есть поле для полета "программерской" фантазии.

В принципе, у меня все. Юзайте!

Нравится

Поделиться

1 комментарий
Показать все комментарии