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

Нашёл следующий подход: в jscript есть функция eval, позволяющая динамически выполнить блок кода.
Пишем кусок скрипта в текстовом файле (я пишу в своей любимой Visual Studio), в терасофте добавляем его
загрузку и выполнение в нужное место, и вуаля - поменяли скрипт, нажали кнопку в клиенте - отработала новая логика,
никаких перезапусков!

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

Вариант кода:

//В администраторе
//Глобальная переменная - чтоб убедиться, что загруженный скрипт видит всё, что видно в функции, из которой вызван eval
var testMessage = 'Printed from loaded script';
function OnEvent()
{
  eval(GetExtScriptText('C:\\Prj\\Terrasoft\\ExtScripts\\DocScripts.js')); // Получили текст скрипта и выполнили его, теперь все функции оттуда нам доступны
  processTestMessage(); //Эта функция описана в скрипте DocScripts.js
}

//Файл DocScripts.js
function oneMoreFunction(messageText){
 return messageText + ' ok.';
}

//Эту функцию мы и вызываем из террасофт. Ей доступна, среди прочего, переменная testMessage
function processTestMessage() {
    var tempString = oneMoreFunction(testMessage);
   
    ShowInformationDialog(tempString);       
}
 

//Функция, которая читает тексовый файл
function GetExtScriptText(scriptFile)
{
 var StringsList = System.CreateObject('TSObjectLibrary.StringsList');
 var FileSystemObject = new ActiveXObject('Scripting.FileSystemObject');

    var File = FileSystemObject.GetFile(scriptFile);

 //Open for reading in default encoding
 var Stream = File.OpenAsTextStream(1, -2);
 try
 {
  while (!Stream.AtEndOfStream)
  {
   StringsList.Add(Stream.ReadLine());
  }
 }
 finally
 {
  Stream.Close();
 }

 return StringsList.Text;
}

Конечно, это не продакшен - вариант, хотя если читать из базы то можно пробовать...
Ещё таким образом можно подсмотреть из внешнего скрипта состояние переменных в карточке у заказчика -
сделать ему кнопку "вызвать скрипт", и по ситуации скрипт можно быстро сваять на месте.
Снова таки актуально только в процессе доводки системы, иначе это уже дырка.

Нравится

Поделиться

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

Сергей, а почему не использовать функцию Main в самом скрипте?
Пишите там код по созданию экземпляра карточки, заполняете нужные атрибуты, вызываете Show(), Prepare(), нажимаете F9 и получаете работающую карточку в администраторе.

Александр, я раньше так и делал...
У нас в этой карточке логика зависит от того, как её создавали (есть несколько вариантов действий, в результате которых вызывается эта карточка в разных режимах - обычный, массовое копирование, изменение, вызов из детали)

Соответственно, я создавал из main весь workspace. Это занимает больше 10 секунд, и при этом не всё работало (возможно, я не до конца корректно его создавал, хотя больше похоже на то, что для корректного создания нужен ещё сервис основного окна). А так - при запущеном клиенте проверить новую функциональность несколько секунд.

Я понял. Да иногда самое сложное - это как раз подготовить параметры для отладки окна. Тогда Ваш способ действительно облегчает отладку.

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

подскажите, пожалуйста, начинающему:
как написать функцию, в которой нужно перебрать продукцию и изменить поле cost = cost * 1.4

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

Нравится

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

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

По поводу простейших скриптов - можно почитать о создании раздела (без использования мастера).

версия 3.0
цель такая: загрузил номенклатуру из 1с, в поле Стоимость - записал себестоимость продукции, теперь нужно увеличить ее на 40%

Если Вы уже произвели импорт из 1С в Terrasoft, то обновлять уже существующие записи лучше с помощью SQL-запроса, выполненного в QueryAnalyzer. Например, такого:

update tbl_Offering
set Cost = Cost * 1.4
where Code1C is not NULL

Пример приведён для условия, когда Вам необходимо обновить записи в разделе "Продукты", которые были импортированы из 1С (поле Code1C у которых - не пустое). Используя данный пример, Вы можете его модифицировать для решения Вашей задачи (зависит от особенностей интеграции с 1С и Вашей конфигурации Terrasoft).

Перед выполнением действий по изменению наполнения БД обязательно сделайте её резервную копию.

Олег Лабьяк,
разработчик,
3-я линия Службы поддержки Terrasoft.

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

Никак не могу понять следующее:

function DataChange(DataField, ScriptObject){
...........
case ('RateAB'):
var RateAB = ValAsFloat(DataFields.ItemsByName('RateAB'));     
if (!ScriptObject.RateABCalculated){                       
                                ScriptObject.RateABCalculated = true;
                            try {      
...........
Dataset.Values('BasicTotalAmount') = Price*Rate*(1-DiscountPercent/100)+DA_noTax+PK*(1-DiscountPercent/100)+AB;
Dataset.Values('BasicTaxAmount') = Price*0.18*Rate*(1-DiscountPercent/100) + Da_Tax+18*AB/100+18*PK/100;
Dataset.Values('TotalBasicAmountWithTax') = Price*Rate*(1-DiscountPercent/100) + Price*0.18*Rate*(1-DiscountPercent/100) +DostAmount+AB+PK+0.18*AB+0.18*PK;


//Dataset.Values('TotalAmount') = Price*(1-DiscountPercent/100)+PK2-PK2*DiscountPercent/100+AB2;       
}
}                              
finally {
                                ScriptObject.RateABCalculated = false;
                                }                              
               
                        break;  
}
}

При изменении поля RateAB все правильно считает, как только снимаю кооментарий со строки
//Dataset.Values('TotalAmount') = Price*(1-DiscountPercent/100)+PK2-PK2*DiscountPercent/100+AB2;

она срабатывает только один раз т.е. допустим в RateAB надо ввести 10, но TotalAmount пересчитывается только при вводе первой цифры 1. Такое случается в разных case-ах, у кого какие мысли?

Нравится

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

А что происходить в обработчике case ('TotalAmount')? Изменяется в нем значение ScriptObject.RateABCalculated?

значение ScriptObject.RateABCalculated в нем не изменяется
пробовал вообще комментировать case ('TotalAmount'), тоже самое.

Попробуйте значение 'TotalAmount' реализовать в case 'DiscountAmount' и 'BasicTotalAmount', в зависимости от соответствующих полей, вместо использования формулы

//Dataset.Values('TotalAmount') = Price*(1-DiscountPercent/100)+PK2-PK2*DiscountPercent/100+AB2; 

В том-то и дело, что все поля взаимосвязанные, значение 'TotalAmount' зависит от напрямую и от RateAB. Просто не могу понять суть проблемы, почему так происходит.

Вы же в зависимости от RateAB подсчитываете BasicTotalAmount. Разве этого не достаточно, чтобы при изменении поля BasicTotalAmount пересчитать TotalAmount с учетов курса?
Обратите внимание на подобные места в скрипте:

if (!ScriptObject.RateABCalculated){                        
  ScriptObject.RateABCalculated = true;

и Вы поймете, когда "включается" пересчет других полей, а когда нет.

Так и поступил

case ('BasicTotalAmount'):
var BasicTotalAmount = ValAsFloat(DataFields.ItemsByName('BasicTotalAmount'));	
if (!ScriptObject.BasicTotalAmount){		  	    
				ScriptObject.BasicTotalAmount = true;
		  	    try {
var Price = Dataset.Values('Price'); 	
var DiscountPercent = Dataset.Values('DiscountPercent');
var PK =  Dataset.Values('PK'); 
var AB =  Dataset.Values('AB'); 
var AB2 = 0;
if (AB > 0 ) {
var AB2 = 0.6 
}
var PK2 = 0;
if (PK > 0){
var PK2 = 3;
}
Dataset('TotalAmount') = Price*(1-DiscountPercent/100)+PK2-PK2*DiscountPercent/100+AB2;		  	    
		  	    }
finally {
	ScriptObject.BasicTotalAmount = false;
     	}				
			break;  
 
}

результат тотже, а можно поподробней насчет

if (!ScriptObject.RateABCalculated){                        
  ScriptObject.RateABCalculated = true;

Вместо

Dataset('TotalAmount') =

лучше использовать функцию

SetFloatDataFieldWithRound(DataField, Value) (описана в scr_DB)

и значения для временных пересенных получайте так:

var X = ValAsFloat(DataFields.ItemsByName('X')); 

а не

var Х = Dataset.Values('Х');

Попробывал Ваш вариент - результат тотже, поле пересчитывается при вводе только первой цифры

Еще раз хочу уточнить, почему Вы, имея значение BssicTotalAmount подсчитываете TotalAmount по какой-то формуле, а не с помощью функции

function CalcNonBasicSum(BasicSum, Rate)

?
Грубо говоря, зачем сложная формула вместо того, чтобы BasicTotalAmount разделить на курс?

TotalAmount у меня несет совершенно друго смысл

В скольких case Вы пересчитываете TotalAmount? И какая логика реализована в case('TotalAmount')?

в одном, case('TotalAmount') вообще сейчас закоментировал

Судя по формуле, TotalAmount зависит от Price и DiscountPercent (а почему не DiscountAmount?). Попробуйте в case этих полей реализовать пересчет TotalAmount.

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

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

Я добавил действие "Создать на основе" и хочу создать новую запись но основе существующей, изменив некоторые поля.
Подскажите, какой наилучший способ это сделать?

Возможно подтянуть запись в датасет, изменить необходимые поля, перегенерировать ID, поставить стейт на "инсерт" и сохранить?

Нравится

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

А разве это нестандартный функционал кнопка копировать?

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

Похожая тема про копирование, вариант решения там есть http://community.terrasoft.ua/forum/topic/3912

Спасибо за ответ.

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

Реестр записей содержит несколько представлений. На нажатие кнопки "Добавить" в форме создания новой записи необходимо проставить некоторые значения в зависимости от выбраного фильтра. Скажите пожалуйста, можно ли узнать какое представление выбрано в обработчике OnPrepare окна создания записи? Или же необходимо записывать его в глобальную переменную в обработчике события ActiveViewChange грида?

Нравится

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

SDK
Смотрите в имя, например :wink:

Спасибо за ответ, но я немного не то спрашивал.
Я имел ввиду можно ли в методах обработки событий формы создания новой записи вытянуть это значение, то есть можно ли доступиться до грида реестра записей. Но я уже сам разобрался как мне реализовать задачу :smile:

хотя, конечно, не уверен насколько я правильно и корректно это сделал, я только начинаю изучать XRM.
В обработчике нажатия кнопки "добавить" я прописал

BaseGridArea.AddDataDefaultValues('ActiveView') = Self.ComponentsByName('grdData').ActiveView.Name;

а потом в функции установки дефолтных значений вытянул при помощи

var ActiveView = GetAttribute(this.scr_WindowUtils.WinCache_Windows[0].Instance, 'DefaultValues')('ActiveView');

Для какого раздела делаете функционал?
Правильнее действовать по следующей схеме:
1) Находим функцию, где устанавливаются значения по умолчанию для окна редактирования. (DefaultValues)
2) В ней проверить какая вкладка была активна. Но лучше использовать метод, когда окно реестра устанавливает еще не открытому окну редактирования дополнительный атрибут, а не наоборот.

Уточните раздел, пожалуйста, тогда ответить будет проще.

Мне кажется, проще было бы в обработчике кнопки добавить название активного представления в атрибуты:

Attributes('ActiveView') = Self.ComponentsByName('grdData').ActiveView.Name;

и в той же функции установки дефолтных значений

var ActiveView = Window.Attributes('ActiveView');

при условии, что эти атрибуты были переданы объекту Window.

Олег Лабьяк,
разработчик,
3-я линия Службы поддержки Terrasoft.

Раздел - Счета.
Функцию нашёл.
Это

FillInvoiceDefaultValues(Dataset)

в файле ds_InvoiceScript

Перекройте обработчик события btnAddOnClick (только не забудьте вызвать базовый) и в нем передавайте значения по умолчанию через BaseGridArea.AddDataDefaultValues, все остальное сделают базовые скрипты.

FillInvoiceDefaultValues(Dataset) изменять в Вашем случае нерационально.

"Агутин Алексей" написал:Перекройте обработчик события btnAddOnClick (только не забудьте вызвать базовый) и в нем передавайте значения по умолчанию через BaseGridArea.AddDataDefaultValues, все остальное сделают базовые скрипты.

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

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

Спасибо огромное.

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

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

Нравится

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

Если одинаковые названия функций, тогда пишите:

Moj_Script.Moja_Function();

--
www.it-sfera.com.ua

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

function wnd_AccountsGridAreaOnPrepare(Window) {
	wnd_BaseGridAreaOnPrepare(Window);
	Initialize(Window);
 
}

Если нужно указать какую именно функцию и в каком скрипте.

scr_BaseGridArea.amGridOnPrepare(ActionMenu, Control);

Если Функция из скрипта, который "приатачен" (Использовать скрипты) то просто вызываете по имени.

"Мамажанов Марат Кадралдыкович" написал:Как можно обращаться к скриптам и функциям из других разделов.

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

"Underscore a.k.a. _" написал:Ато обращаться из раздела к функциям скриптов других разделов не есть хорошо.

+1 да-да!

--
www.it-sfera.com.ua

Нехорошо, но встречается )

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

"Глова Сергей" написал:Нехорошо, но встречается )

Я уже кажется писал где-то про линейку :)

Да, было дело:smile:
Рефакторинг штука сложная

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

Подскажите, пожалуйста, существует ли возможность вызвать некоторую функцию скрипта Terrasoft из MS SQL?

Нравится

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

Можно. Там только с передачей и возвратом параметров очень сложно.

Насколько я понимаю (речь идет не о вызове функции SQL из TS, а наоборот) - нельзя... наверное :)

--
www.it-sfera.com.ua
Terrasoft Solution Partner

Насколько помню, объекты в SQL можно создавать. А там надо смотреть IScript::ExecuteMethod в SDK. Но есть нюансы - Connector и параметры.
Когда то приходилось такое делать, но не в MS SQL.

Думаю Сергей прав. Раз все сделано на COM-ах и сервер умеет с ними работать, то теоретически это возможно. Но я бы поискал другой путь. Ато сверлить зуб бормашиной с приводом от ядерного реактора, котрый находится в кабинете врача и раскочегаривается в присутствии пациента... :)

+1

--
www.it-sfera.com.ua
Terrasoft Solution Partner

Олег, а зачем Вам такая возможность, для какой задачи?
Oracle предоставляет возможность писать встроенные функции на java и c, может, пригодиться )

Необходимо выполнять некоторые действия системы с некоторой периодичностью, к примеру, каждый час.
В данном случаи используется MS SQL.

Может, эти задачи можно решить с помощью триггеров или job'ов?

+1 за

"Лабьяк Олег Игоревич" написал:триггеров или job'ов

--
www.it-sfera.com.ua
Terrasoft Solution Partner

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

"Кулак Олег" написал:
Необходимо выполнять некоторые действия системы с некоторой периодичностью

Олег, вот тут конечно необходимо уточнить информацию:
1. Если здесь Вы активно работаете с данными, то однозначно - job + хранимая процедура на T-SQL
2. Если там очень сложная логика и работает не только с данными, но и испрользуете сложные математические расчеты, то можно глянуть в сторону DTS пакетов, где можно писать на VB.
3. Если все-таки очень сложная логика и Вы не хотите тратить время на переписывание ее с JScript на другой язык, то можно попробовать вызвать функцию на стороне MSSQL.

Изменилась немного постановка задачи.
В общих чертах, теперь нужно в определенное время выгружать данные из базы MS SQL во внешний файл.
Может кто-то сможет подсказать, как это реализовать при помощи job'а и франимки?

Я бы рекомендовал воспользоваться утилитой bcp, в job-е можно вызвать не только T-SQL. Вот пример сохранения результата запроса в csv файл:

bcp "select * from master.sys.objects" queryout master.sys.objects.csv -c -S "MYSERVER\MSSQL2008" -T -t ;

Спасибо. Буду пробовать.

Кстати если нужно будет потом загрузить данные в другую БД то рекомендую использовать эту же утилиту. Данные просто "влетают" в БД (100 тыс. за секунды) или команда T-SQL:

BULK INSERT

Не знаю почему, но для выгрузки такой команды нет.

Еще раз спасибо.

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

Пришлось столкнуться с проблемой, когда у клиента возникали "специфические" ошибки следующего характера:

The following error(s) have occurred: Оригинальное сообщение об ошибке: I/O error (bad page ID) detected during read at offset 0x00000010a5c000 in fileC:\terrasoft\Data\terrasoftCRM 30x15 Rus.mdf

Ошибка сохранения записи. Оригинальное сообщение об ошибке: I/O error (bad page ID) detected during read at offset 0x00000010a58000 in fileC:\terrasoft\Data\terrasoftCRM 30x15 Rus.mdf

Оригинальное сообщение об ошибке: Could not find the index entry for RID '16f1d2207bc9455f408a6e73882fe163ff010000' in index page (1:498400), index ID 0, database 'TSCRM30'. «Call Stack»

Данная ошибка возникает при сбоях сервера базы данных. Для решения нужно выполнить скрипт, на базе данных с помощью Query Analyzer или Management Studio:

USE master

go

ALTER DATABASE Название_базы SET single_user

go

USE Название_базы

go

DBCC CHECKDB ('Название_базы', repair_allow_data_loss)

go

ALTER DATABASE Название_базы SET multi_user

go

С помощью данного запроса починили уже две базы клиентов.

Может кому-то еще пригодится!;)

Нравится

Поделиться

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

Есть одно небольшое замечание
DBCC CHECKDB с параметром repair_allow_data_loss
может привести к потере данных и, возможно, к нарушению логической целостности системы

Рекомендуется
- использовать резервные копии
- сначала запускать
DBCC CHECKDB с опцией repair_rebuild и только - если данный вариант не поможет (в самом крайнем случае, если нет другого выхода), то с опцией repair_allow_data_loss

См.документацию
DBCC CHECKDB (Transact-SQL)

Тоже поделюсь опытом:)
Конечно такие критические ошибки появляются не просто так, а как правило это происходит когда кто-то изменяет данные в базе данных а при этом .... выключается свет или кто-то кнопочку ВЫКЛ нажал на сервере(бывает даже такое, что вместо сервера используется ПК какого-то сотрудника :)). Все было бы хорошо если бы на сервере баз данных стоял UPS, а как правило на это не обращают пока гром не грянет. dbcc checkdb не всегда может помочь, хотя конечно и меня спасал :) А вот если уж случилась данная проблема, то я бы рекомендовал сделать следующее:
1. Попробовать варианты с dbcc checkdb
2. Если Вам повезло, то создать полную копию базы или из бекапа с инсталяции или sql скриптами и с помощью утилит Import/Export, SSIS "перелить" данные в новую базу и... поставить UPS на сервер, настроить автоматический бекап с верификацией и жить спокойно :)
3. Если все таки некоторые таблицы нельзя восстановить то, у меня получалось вытянуть данные из таких таблиц с помощью select top ... пакетами и "перелить" их в чистую копию.
Может повезет и Вы сможете вытянуть побольше:)

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

Здравствуйте. У меня CRM X15 версии 3.2.0.11 стандартной конфигурации. Стоят следующии задачи:
1) при создании новой задачи автоматически запускать таймер (аналогично "действия->запустить таймер", только делать это программно).
2) при закрытии задачи сделать обязательным поле "подробный результат". То есть чтобы пользователь не мог закрыть задачу, не заполнив это поле.
Как мне это сделать? Заранее большое спасибо за помощь!

Нравится

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

1)var Timer = System.CreateObject('TSWindowLibrary.Timer');
зачем его создавать , я понять немогу
2) в окне редактирования задач , на событии OnDatasetDataChange

function dlDataOnDatasetDataChange(DataField) {
if (!Assigned(DataField)) {
return;
}
var DataFieldName = DataField.Name;
if (DataFieldName == 'StatusID'){
if (DataField.Value == 'айдишник состояния выполнено' ){
dlData.Dataset.DataFields('ResultID').IsRequired = true;
} else {
dlData.Dataset.DataFields('ResultID').IsRequired = false;
}

}
}

Вместо последнего if я бы написал

dlData.Dataset.DataFields('ResultID').IsRequired = (DataField.Value == 'айдишник состояния выполнено');

Спасибо, со 2-м пунктом разобрался, а вот с первым нет. Имелось ввиду что менеджеры, когда создают задачу (чаще всего они создают ее себе сами) часто забывают запутить таймер ее выполнения со всеми вытекающими отсюда последствиями.
Руководитель отдела попросил меня, чтобы это делалось автоматически, т.к. в 90% случаев факт того, что менеджер завел задачу ознает что он уже начал ее выполнять, то есть логично было бы запускать его автоматически, а не совершать дополнительное ручное действие.

Заранее спасибо за помощь!

можно попробовать изменить под себя функцию StartTimer()
которая находится в scr_TasksWorkspace
но она может неработать для вновь созданых задачь

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

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

--обновляет средсва связей и адреса контактов по их контрагентам.
--Детали адреса и средства связей контактов наполняются по их контрагентам, при этом старые записи остаются
-- если старые записи не нужны убрать/закомментировать строчку помеченную /*!!!*/
declare @NeedOldDetailRecords int
set @NeedOldDetailRecords = 0
set @NeedOldDetailRecords = 1   /*!!!*/


print 'Update tbl_Contact'
update t1
set     t1.Communication1=t2.Communication1,
    t1.Communication2=t2.Communication2,
    t1.Communication3=t2.Communication3,
    t1.Communication4=t2.Communication4,
    t1.Communication1TypeID=t2.Communication1TypeID,
    t1.Communication2TypeID=t2.Communication2TypeID,
    t1.Communication3TypeID=t2.Communication3TypeID,
    t1.Communication4TypeID=t2.Communication4TypeID,
    t1.TerritoryID    =t2.TerritoryID,
    t1.AddressTypeID =t2.AddressTypeID,
    t1.CountryID =t2.CountryID,
    t1.StateID =t2.StateID,
    t1.CityID =t2.CityID,
    t1.ZIP =t2.ZIP,
    t1.Address =t2.Address
from tbl_Contact t1, tbl_Account t2
where t1.AccountID is not null
and t2.id=t1.AccountID

if @NeedOldDetailRecords = 1
begin
    print 'update tbl_ContactCommunication'
    update tbl_ContactCommunication
    set position = null
    where exists(select * from tbl_Contact t2 where tbl_ContactCommunication.ContactID=t2.ID and t2.AccountID is not null)
   
    print 'update tbl_ContactAddress'
    update tbl_ContactAddress
    set IsPrimary = null
    where exists(select * from tbl_Contact t2 where tbl_ContactAddress.ContactID=t2.ID and t2.AccountID is not null)
end
if @NeedOldDetailRecords = 0
begin
    print 'delete from tbl_ContactAddress'
    delete tbl_ContactAddress
    from tbl_ContactAddress t1
    where exists(select * from tbl_Contact t2 where t1.ContactID=t2.ID and t2.AccountID is not null)
   
    print 'delete from tbl_ContactCommunication'
    delete tbl_ContactCommunication
    from tbl_ContactCommunication t1
    where exists(select * from tbl_Contact t2 where t1.ContactID=t2.ID and t2.AccountID is not null)
end

print 'Insert into tbl_ContactAddress'
insert into tbl_ContactAddress(id,ContactID,AddressTypeid,Address,CityID,StateID, Zip, CountryID, IsPrimary, TerritoryID)
select newid(), t1.id, t3.AddressTypeid, t3.Address, t3.CityID, t3.StateID, t3.Zip, t3.CountryID, t3.IsPrimary, t3.TerritoryID
from tbl_Contact t1, tbl_Account t2, tbl_AccountAddress t3
where t1.accountid is not null
and t1.accountid=t2.id
and t2.id=t3.accountid

print 'Insert into tbl_ContactCommunication'
insert into tbl_ContactCommunication(id,ContactID,Number,CommunicationTypeID,Position,Digits)
select newid(), t1.id, t3.Number, t3.CommunicationTypeID, t3.Position, t3.Digits
from tbl_Contact t1, tbl_Account t2, tbl_AccountCommunication t3
where t1.accountid is not null
and t1.accountid=t2.id
and t2.id=t3.accountid

С уважением,
Коваленко Ирина

Нравится

Поделиться

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