Вывод результата запроса на форму УП в таблицу значений (аналог СоздатьКолонки() для УП) при разработке на обычных формах было удобно выводить результат запроса используя метод СоздатьКолоки():
Код 1C v 8.х Процедура ПоискНажатие(Элемент)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДокументоОборот.Этап,
| ДокументоОборот.Отдел,
| ДокументоОборот.ФИО,
| ДокументоОборот.ДатаВремя КАК Дата_Время,
| ДокументоОборот.Документы,
| ДокументоОборот.Примечание,
| ДокументоОборот.Доставка
|ИЗ
| РегистрСведений.ДокументоОборот КАК ДокументоОборот
|ГДЕ
| ДокументоОборот.Документы ПОДОБНОДокументы
| И ДокументоОборот.Доставка.Дата МЕЖДУДатаН ИДатаК
|
|УПОРЯДОЧИТЬ ПО
| ДокументоОборот.ДатаВремя";
Запрос.УстановитьПараметр("Документы", "%"+СокрЛП(Строка(СтрокаПоиска))+"%");
Запрос.УстановитьПараметр("ДатаК", КонПериода);
Запрос.УстановитьПараметр("ДатаН", НачПериода);
Рез=Запрос.Выполнить();
НайденДок = рез.Выгрузить();
ЭлементыФормы.НайденДок.СоздатьКолонки();
В управляемом приложении метод СоздатьКолоки() не доступен, ниже представлена процедура, которая отображает на управляемой форме содержимое таблицы значений переданное ей в качестве параметра:
Пример формы:
Код вывода результата запроса на управляемую форму :
Код 1C v 8.2 УП &НаСервере
Процедура СоздатьТаблицуФормы(Знач ИмяПоляТаблицыФормы, Знач ИмяРеквизитаДанныеФормыКоллекция, Знач ТаблицаЗначений)
// Если руками не создали эелемент формы Таблица, то создается программно
Если Элементы.Найти(ИмяПоляТаблицыФормы) = Неопределено Тогда
ЭлементРеквизита = Элементы.Добавить(ИмяПоляТаблицыФормы, Тип("ТаблицаФормы"),);
ЭлементРеквизита.ПутьКДанным = ИмяРеквизитаДанныеФормыКоллекция;
КонецЕсли;
УдаляемыеРеквизиты = Новый Массив;
РеквизитыДляУдаления = ПолучитьРеквизиты(ИмяРеквизитаДанныеФормыКоллекция);
Для Каждого РеквизитУдаления Из РеквизитыДляУдаления Цикл
УдаляемыеРеквизиты.Добавить(ИмяРеквизитаДанныеФормыКоллекция+"."+РеквизитУдаления.Имя);
// Удаляем элементы формы
Элементы.Удалить(Элементы[ИмяПоляТаблицыФормы+РеквизитУдаления.Имя]);
КонецЦикла;
// Добавление реквизитов в таблицу формы
ДобавляемыеРеквизиты = Новый Массив;
Для каждого Колонка Из ТаблицаЗначений.Колонки Цикл
ДобавляемыеРеквизиты.Добавить(Новый РеквизитФормы(Колонка.Имя, Колонка.ТипЗначения, ИмяРеквизитаДанныеФормыКоллекция, Колонка.Заголовок));
КонецЦикла;
ИзменитьРеквизиты(ДобавляемыеРеквизиты,УдаляемыеРеквизиты);
// Добавление элементов форму
Для каждого Колонка Из ТаблицаЗначений.Колонки Цикл
ЭлементРеквизита = Элементы.Добавить(ИмяПоляТаблицыФормы + Колонка.Имя, Тип("ПолеФормы"), Элементы[ИмяПоляТаблицыФормы]);
ЭлементРеквизита.ПутьКДанным = ИмяРеквизитаДанныеФормыКоллекция + "." + Колонка.Имя;
ЭлементРеквизита.Вид = ВидПоляФормы.ПолеВвода;
КонецЦикла;
ЗначениеВРеквизитФормы(ТаблицаЗначений, ИмяРеквизитаДанныеФормыКоллекция);
КонецПроцедуры
&НаСервере
Процедура ВПоискНаСервере()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РеализацияТоваровУслугСерии.Серия КАК Серия,
| РеализацияТоваровУслугСерии.Ссылка КАК Реализация,
| РеализацияТоваровУслугСерии.Ссылка.ЗаказКлиента КАК ЗаказКлиента,
| РеализацияТоваровУслугСерии.Ссылка.Контрагент КАК Контрагент,
| РеализацияТоваровУслугСерии.Ссылка.Договор КАК Договор
|ИЗ
| Документ.РеализацияТоваровУслуг.Серии КАК РеализацияТоваровУслугСерии
|ГДЕ
| РеализацияТоваровУслугСерии.Серия В
| (ВЫБРАТЬ
| СерииНоменклатуры.Ссылка КАК Ссылка
| ИЗ
| Справочник.СерииНоменклатуры КАК СерииНоменклатуры
| ГДЕ
| СерииНоменклатуры.Наименование ПОДОБНОНаименование)
|
|УПОРЯДОЧИТЬ ПО
| Серия
|АВТОУПОРЯДОЧИВАНИЕ";
Запрос.УстановитьПараметр("Наименование", "%"+НомерФН+"%");
РезультатЗапроса = Запрос.Выполнить();
ТаблицаЗапроса = Запрос.Выполнить().Выгрузить();
СоздатьТаблицуФормы("ТЗ","ТЗ",ТаблицаЗапроса);
КонецПроцедуры
&НаКлиенте
Процедура ВПоиск(Команда)
ВПоискНаСервере();
КонецПроцедуры
Категория:
Управляемое приложение, Тонкий клиент Google maps : вывод точек на карту и режим панорамы В отличие от яндекс карт в GMaps можно использовать панорамы - за что им большой плюс! Надеюсь в яндексе прочитают этот пост и тоже когда-нибудь это сделают!
Для клиента нужно было сделать вывод объектов на карту
С возможностью просмотра панорамы:
Основной HTML код карты хранится в макете:
Код VBS <!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=8">
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0px; padding: 0px }
#map { height: 100% }
</style>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3.9&sensor=false"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript" src="http://www.sitedev.by/lab/markerclusterer/markerclusterer.js"></script>
<script type="text/javascript">
var latlng;
var markers = [];
var myMap;
var index = 1;
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var infoWindow = new google.maps.InfoWindow;
var clusterer, mcOptions;
var trafficLayer = new google.maps.TrafficLayer();
var trafficOn = false;
var noclick = false;
var PointArray = [];
var polygons = [];
function initialize() {
directionsDisplay = new google.maps.DirectionsRenderer();
latlng = new google.maps.LatLng(55.75, 37.62);
var myOptions = {
zoom: 12,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDoubleClickZoom: true,
panControl: true,
zoomControl: true,
mapTypeControl: true,
scaleControl: true,
streetViewControl: true,
overviewMapControl: true
};
myMap = new google.maps.Map(document.getElementById("map"),
myOptions);
google.maps.event.addListener(myMap, 'dragend', function() {
noclick = true;
document.getElementById('CoordX').value = "0";
document.getElementById('CoordY').value = "0";
});
google.maps.event.addListener(myMap, 'click', function(event) {
infoWindow.close();
if (!noclick) {
addMarker(event.latLng);
}else{
noclick = false;
}
});
mcOptions = {gridSize: 3, maxZoom: 15};
clusterer = new MarkerClusterer(myMap, markers, mcOptions);
//отображение кнопки управления трафиком - все спер с примера, только подцепил свою функцию
var trafficControlDiv = document.createElement('div');
trafficControlDiv.style.padding = '5px';
// Set CSS for the control border
var controlUI = document.createElement('div');
controlUI.style.backgroundColor = 'white';
controlUI.style.borderStyle = 'solid';
controlUI.style.borderWidth = '2px';
controlUI.style.cursor = 'pointer';
controlUI.style.textAlign = 'center';
controlUI.title = 'нажмите для вкл/выкл трафика';
trafficControlDiv.appendChild(controlUI);
// Set CSS for the control interior
var controlText = document.createElement('div');
controlText.style.fontFamily = 'Arial,sans-serif';
controlText.style.fontSize = '12px';
controlText.style.paddingLeft = '4px';
controlText.style.paddingRight = '4px';
controlText.innerHTML = '<b>Трафик</b>';
controlUI.appendChild(controlText);
google.maps.event.addDomListener(controlUI, 'click', function (){
if (!trafficOn){
trafficOn = true;
trafficLayer.setMap(myMap);
}else{
trafficOn = false;
trafficLayer.setMap(null);
}
});
trafficControlDiv.index = 1;
myMap.controls[google.maps.ControlPosition.TOP_RIGHT].push(trafficControlDiv);
};
//добавляем маркер и отправляем в массив
function addMarker(location) {
marker = new google.maps.Marker({
position: location,
map: myMap,
title: 'Точка'+index
});
infoWindow.setContent(marker.title);
infoWindow.open(myMap, marker);
google.maps.event.addListener(marker, 'click', function(){
var mark = this;
var latLng = mark.getPosition();
infoWindow.setContent(mark.title);
infoWindow.open(myMap, mark);});
markers.push(marker);
index++;
document.getElementById('CoordX').value = location.lat();
document.getElementById('CoordY').value = location.lng();
}
function calcRoute(options) {
//вытягиваем из массива переданных параметров значения
//и преобразуем их в формат LatLng
var option1 = options[0];//начальная точка
var option2 = options[1];//промежуточные точки
var option3 = options[2];//конечная точка
var start = new google.maps.LatLng(option1[0], option1[1]); //первый
var end = new google.maps.LatLng(option3[0], option3[1]); //последний
//получаем транзитные точки
var waypts = [];
if(option2.length > 0) {
for(var i = 0, l = option2.length; i < l; i++) {
temp = option2[i];
Qcoord = new google.maps.LatLng(temp[0], temp[1])
waypts.push({
location:Qcoord,
stopover:true
});
}
}
//return;
var request = {
origin: start,
destination: end,
waypoints: waypts,
optimizeWaypoints: true,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setMap(myMap);
directionsDisplay.setDirections(response);
var total = 0;
var myroute = response.routes[0];
for (i = 0; i < myroute.legs.length; i++) {
total += myroute.legs[i].distance.value;
}
total = total / 1000;
document.getElementById('RouteInfo').value = "Длина маршрута - " + total + "км.";
//генерация события для перехвата в 1С
var evt = document.createEventObject();
document.body.fireEvent('ondatasetcomplete', evt);
}else{
alert(status);
}
});
}
function Reset(){
directionsDisplay.setMap(null);
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
markers = [];
index = 1;
//обнуляем кластер маркеров
clusterer.clearMarkers();
for (var i = 0; i < polygons.length; i++) {
polygons[i].setMap(null);
}
polygons = [];
PointArray = [];
}
function FindAdres(Adres){
Reset();
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': Adres}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
latlng = results[0].geometry.location;
myMap.panTo(latlng);
marker = new google.maps.Marker({
map: myMap,
position: latlng,
animation: google.maps.Animation.BOUNCE,
title:Adres
});
markers.push(marker);
infoWindow.setContent(marker.title);
infoWindow.open(myMap, marker);
} else {
alert("Ничего не найдено: " + status);
}
});
}
function ReverseSearchAdres(CoordX, CoordY, Adres){
Reset();
latlng = new google.maps.LatLng(CoordX, CoordY);
myMap.panTo(latlng);
var marker = new google.maps.Marker({
map: myMap,
position: latlng,
animation: google.maps.Animation.BOUNCE,
title:Adres
});
markers.push(marker);
infoWindow.setContent(marker.title);
infoWindow.open(myMap, marker);
}
function addToPointArray(CoordX, CoordY, ID, IconT, Text){
var latLng = new google.maps.LatLng(CoordX, CoordY);
var point = new google.maps.Marker({'position': latLng, title: Text, icon: IconT});
PointArray.push(point);
}
function drawCluster(){
clusterer.addMarkers(PointArray);
//myMap.geoObjects.add(clusterer);
}
function createPolygon(ArrayPoint, Name, color) {
//создаем массив координат вершин многоугольника
var paths = [];
for(var i = 0, l = ArrayPoint.length; i < l; i++) {
var temp = ArrayPoint[i];
Qcoord = new google.maps.LatLng(temp[0], temp[1])
paths.push(Qcoord);
};
// Создаем многоугольник
myPolygon = new google.maps.Polygon({
paths: paths,
strokeColor: color,
strokeOpacity: 0.6,
strokeWeight: 5,
fillColor: "#0000FF"
});
myPolygon.setMap(myMap);
polygons.push(myPolygon);
}
function WebClientClick() {
//очистка перед кликом координат, иначе после клика в упр. формах идет считывание координат
document.getElementById('CoordX').value = "0";
document.getElementById('CoordY').value = "0";
var WebClientOperation = document.getElementById("WebClientOperation").value;
//alert(WebClientOperation);
switch (WebClientOperation) {
case "0": // ничего не делаем
var a = 1;
default: // запускаем функцию
eval(WebClientOperation);
}
document.getElementById('WebClientOperation').value = "0";
}
</script>
</head>
<body onload="initialize()">
<div id="map" style="width:100%; height:100%"></div>
<input type="hidden" id="CoordX" name="CoordX" value="0"></input>
<input type="hidden" id="CoordY" name="CoordY" value="0"></input>
<input type="hidden" id="RouteInfo" name="RouteInfo" value=""></input>
<input type="hidden" id="WebClientOperation" name="WebClientOperation" value="0"></input>
<input type="hidden" id="WebClient" name="WebClient" onclick="WebClientClick();"></input>
</body>
</html>
Код вывода карты:
Код 1C v 8.х Процедура ИнициализироватьКарту()
ПутьКФайлу = КаталогВременныхФайлов()+"Карта.html";
Ф = новый Файл(ПутьКФайлу);
Если Ф.Существует() Тогда
УдалитьФайлы(ПутьКФайлу);
КонецЕсли;
Т = новый ТекстовыйДокумент;
ТД = ЭтотОбъект.ПолучитьМакет("МакетГугл");
Т.УстановитьТекст(ТД.ПолучитьТекст());
Т.Записать(ПутьКФайлу);
ЭлементыФормы.Эксплорер.Перейти(ПутьКФайлу);
КонецПроцедуры
Процедура ОчиститьКарту()
ЭлементыФормы.Эксплорер.Документ.parentWindow.eval("Reset()");
КонецПроцедуры
//к сожалению, другого спососба получить "внутрь 1С" информацию о действии пользователя на карте я не сумел
//действие пользователя на карте изменяет поле HTML-документа, но не вызывает никакого события в 1с-ке
// поэтому через обработчикОжидания делаю непрерывный опрос карты
Процедура ПриОткрытии()
ИнициализироватьКарту();
КонецПроцедуры
// вывод точек на карту
Процедура ОсновныеДействияФормыОсновныеДействияФормыВыполнить(Кнопка)
ОчиститьКарту();
СписокВидов = Новый СписокЗначений;
Для Каждого стр из ВыборВывода Цикл
если стр.пометка тогда СписокВидов.Добавить(стр.наименование); КонецЕсли;
КонецЦикла;
табАдресов.Очистить();
табАдресов = получитьтабАдресов(СписокВидов);
табУникальныхАдресов = табАдресов.скопировать();
табУникальныхАдресов.свернуть("Уник");
тзДанных = табАдресов.скопировать();
табАдресов.очистить();
Для Каждого стр из табУникальныхАдресов Цикл
Отбор = Новый Структура();
Отбор.Вставить("Уник",стр.Уник);
Строки = тзДанных.НайтиСтроки(Отбор);
НовСтр = табАдресов.добавить();
НовСтр.уник = стр.уник;
Если Строки.Количество() > 0 Тогда
для Каждого тздстр из Строки Цикл
НовСтр.Адрес = тздстр.Адрес;
НовСтр.КД = тздстр.КД;
НовСтр.КШ = тздстр.КШ;
НовСтр.ВидОбъекта = тздстр.ВидОбъекта;
НовСтр.Наименование=Строка(НовСтр.Наименование)+Строка(тздстр.Наименование)+"; ";
КонецЦикла;
КонецЕсли;
КонецЦикла;
ЭлементыФормы.табАдресов.СоздатьКолонки();
ВыборМасштаба = "50%";
ВыборРегиона = "Москва";
ЭлементыФормы.Надпись24.Заголовок = "Точек: "+Строка(табАдресов.количество());
Кол = табАдресов.Количество();
Индекс = 0;
Для Каждого ТекСтрока Из табАдресов Цикл Индекс = Индекс + 1; Если НЕ ЗначениеЗаполнено(ТекСтрока.КД) тогда Продолжить; КонецЕсли;
Широта = формат(ТекСтрока.КШ, "ЧРД=.");
Долгота = формат(ТекСтрока.КД, "ЧРД=.");
СодержимоеТочки = СокрЛП(ТекСтрока.ВидОбъекта)+": "+ СокрЛП(ТекСтрока.адрес); //опять же можно вставить свое название
Попытка
ЭлементыФормы.Эксплорер.Документ.parentWindow.eval("addToPointArray(" + Широта + "," + Долгота + ", '" + Строка(Индекс) + "', '" + СокрЛП(ТекСтрока.ВидОбъекта.ПутьКИконке)+ "', """ + СодержимоеТочки + """);");
Исключение
Сообщить("addToPointArray(" + Широта + "," + Долгота + ", '" + Строка(Индекс) + "', '" + СокрЛП(ТекСтрока.ВидОбъекта.ПутьКИконке)+ "', """ + СодержимоеТочки + """);",СтатусСообщения.Внимание);
КонецПопытки;
Состояние("Вывожу на карту " + Индекс + " из " + кол);
КонецЦикла;
ЭлементыФормы.Эксплорер.Документ.parentWindow.eval("drawCluster();");
КонецПроцедуры
Вырванная из конфигурации обработка GMaps.rar
Можно ее использовать как макет для создания обработки под свои требования.
Пример автоматизации в котором это использовалось.
Категория:
Географическая схема Яндекс карта : вывод точек на карту Пример о том,как вывести яндекс карту на форму и далее работать с ней:
Основной HTML код карты хранится в макете:
Код VBS <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Примеры. Геокодирование.</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="http://api-maps.yandex.ru/1.1/index.xml?key=ANpUFEkFAAAAf7jmJwMAHGZHrcLKDsbEqEVjEUtCmufxQMwAAAAAAAAAAAAvVrubVT4btztbduoIgTLAeFILaQ==" type="text/javascript"></script>
<script type="text/javascript">
var router;
var myPoints = new Array();
var myRouts = new Array();
var strOpen = "OPEN";
var strKontr = "Kontragent";
var t = new YMaps.Template('<b>$[name]</b><div id="descrID" >$[description]</div>');
YMaps.Templates.add("my#template", t);
var KopdinatShirota = 0;
var KopdinatDolgota = 0;
var UID_Zakaza = "";
/*vstavkaStiley;
var map, geoResult;
YMaps.jQuery(function () {
map = new YMaps.Map(YMaps.jQuery("#YMapsID")[0]);
map.setCenter(new YMaps.GeoPoint(37.62, 55.75), 12);
});
function showAddress (value, contrag, Styles, UID) {
var geocoder = new YMaps.Geocoder(value, {results: 1, boundedBy: map.getBounds()});
YMaps.Events.observe(geocoder, geocoder.Events.Load, function () {
if (this.length()) {
geoResult = this.get(0);
var point = new YMaps.GeoPoint(geoResult._point.__lng, geoResult._point.__lat);
var placemark = new YMaps.Placemark(point, {style: Styles});
placemark.name = UID;
placemark.description = contrag;
myPoints.push(placemark);
map.addOverlay(placemark);
return placemark;
}else {
}
});
YMaps.Events.observe(geocoder, geocoder.Events.Fault, function (geocoder, error) {
alert("Произошла ошибка: " + error);
return null;
})
}
function showAddressCoord (shirota, dolgota, contrag, Styles, UID) {
var point = new YMaps.GeoPoint(dolgota, shirota);
var placemark = new YMaps.Placemark(point, {style: Styles});
placemark.name = UID;
placemark.description = contrag;
myPoints.push(placemark);
map.addOverlay(placemark);
return placemark;
}
function removeAllOverlays (map) {
map.removeAllOverlays();
}
function AddRoute(wayPoint1, wayPoint2) {
if (myRouts.length>0) {lastRouter = myRouts[myRouts.length-1]; map.removeOverlay(lastRouter)};
var myRouter = new YMaps.Router([wayPoint1, wayPoint2], [], {viewAutoApply: true});
map.addOverlay(myRouter);
YMaps.Events.observe(myRouter, myRouter.Events.Success, function (myRouter) {
myRouter.getWayPoint(0).setIconContent('Начало маршрута');
myRouter.getWayPoint(1).setIconContent('Конец маршрута');
dlMar = myRouter.getDistance()/1000;
document.title = 'Дистанция: '+ dlMar.toFixed(2);
});
myRouts.push(myRouter);
return true;
}
function mapRazmer(map, SentrSh, SentrDlg, razmer) {
map.setCenter(new YMaps.GeoPoint(SentrSh, SentrDlg), razmer);
}
function changeStyle(numTochki, imStyle){
var restoreDefault = true;
tochka = myPoints[numTochki];
tochka.setOptions({style: imStyle}, restoreDefault);
point = tochka.getCoordPoint();
map.setCenter(new YMaps.GeoPoint(point.__lng, point.__lat), 12);
map.redraw();
return tochka.description;
}
</script>
</head>
<body //~~onload~~>
<div id="YMapsID" style="width:100%;height:100%"></div>
</form>
</body>
</html>
Код вывода карты:
Код 1C v 8.х //берем HTML-текст из макета и доделываем его
//создаем столько стилей, сколько есть различных картинок в папке "icons_"
//Загружаем в поле HTML-документа
//и позиционируем центр карты на Москву
Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
Макет = ПолучитьМакет("Макет");
КодХТМЛ = Макет.ПолучитьТекст();
СтрокаСтиляНачальная = "var BurG = new YMaps.Style();
|BurG.iconStyle = new YMaps.IconStyle();
|BurG.iconStyle.offset = new YMaps.Point(-12, -12);
|BurG.iconStyle.href = ""http://www.burgerking.ru/favicon.ico"";
|BurG.iconStyle.size = new YMaps.Point(20, 20);
|BurG.hideIcon = false;
|BurG.balloonContentStyle = new YMaps.BalloonContentStyle(""my#template"");";
СтрокаСтиляИтоговая = "";
//
//имяКаталогаКартинок = "D:\!1C\MAPS\icons_";
//КаталогКартинок = Новый Файл(имяКаталогаКартинок);
//Если КаталогКартинок.ЭтоКаталог() тогда
// списокИменКартинок = новый таблицаЗначений;
// списокИменКартинок.Колонки.Добавить("ИмяСтиля");
// списокИменКартинок.Колонки.Добавить("ИмяФайлаКартинки");
// МассивНайденных = НайтиФайлы(имяКаталогаКартинок, "*.gif");
// Для Каждого Файл из МассивНайденных Цикл
//
// времСтрокаСтиля = СтрокаСтиляНачальная;
// времСтрокаСтиля = стрЗаменить(времСтрокаСтиля, "BurG", сокрЛП(Файл.ИмяБезРасширения));
// времСтрокаСтиля = стрЗаменить(времСтрокаСтиля, "C:/icons_/kv2_5_x.gif", "C:/icons_/" + сокрЛП(Файл.Имя));
//
// СтрокаСтиляИтоговая = СтрокаСтиляИтоговая + времСтрокаСтиля + символы.ПС;
//
// КонецЦикла;
//конецЕсли;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВидыОбъектов.Ссылка,
| ВидыОбъектов.ПутьКИконке,
| ВидыОбъектов.Код
|ИЗ
| Справочник.ВидыОбъектов КАК ВидыОбъектов
|ГДЕ
| ВидыОбъектов.ПометкаУдаления = ЛОЖЬ";
Результат = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = Результат.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
времСтрокаСтиля = СтрокаСтиляНачальная;
времСтрокаСтиля = стрЗаменить(времСтрокаСтиля, "BurG", "s"+Строка(ВыборкаДетальныеЗаписи.код));
времСтрокаСтиля = стрЗаменить(времСтрокаСтиля, "http://www.burgerking.ru/favicon.ico", сокрЛП(ВыборкаДетальныеЗаписи.ПутьКИконке));
СтрокаСтиляИтоговая = СтрокаСтиляИтоговая + времСтрокаСтиля + символы.ПС;
КонецЦикла;
СтрокаСтиляИтоговая = СтрокаСтиляИтоговая + СтрокаСтиляНачальная + символы.ПС;
КодХТМЛ = стрЗаменить(КодХТМЛ, "/*vstavkaStiley;", СтрокаСтиляИтоговая);
путьККаталогуКартинок = СтрЗаменить(КаталогПрограммы(), "\", "/");
КодХТМЛ = СтрЗаменить(КодХТМЛ,"C:/",путьККаталогуКартинок);
ЭлементыФормы.Карта.УстановитьТекст(КодХТМЛ);
табАдресов = получитьтабАдресов();
табУникальныхАдресов = табАдресов.скопировать();
табУникальныхАдресов.свернуть("Уник");
тзДанных = табАдресов.скопировать();
табАдресов.очистить();
Для Каждого стр из табУникальныхАдресов Цикл
Отбор = Новый Структура();
Отбор.Вставить("Уник",стр.Уник);
Строки = тзДанных.НайтиСтроки(Отбор);
НовСтр = табАдресов.добавить();
НовСтр.уник = стр.уник;
Если Строки.Количество() > 0 Тогда
для Каждого тздстр из Строки Цикл
НовСтр.Адрес = тздстр.Адрес;
НовСтр.КД = тздстр.КД;
НовСтр.КШ = тздстр.КШ;
НовСтр.ВидОбъекта = тздстр.ВидОбъекта;
НовСтр.Наименование=Строка(НовСтр.Наименование)+Строка(тздстр.Наименование)+"; ";
КонецЦикла;
КонецЕсли;
КонецЦикла;
ЭлементыФормы.табАдресов.СоздатьКолонки();
ВыборМасштаба = "50%";
ВыборРегиона = "Москва";
ЭлементыФормы.Надпись24.Заголовок = "Точек: "+Строка(табАдресов.количество());
КонецПроцедуры
// Вывод точек на карту
Процедура ОсновныеДействияФормыОсновныеДействияФормыВыполнить(Кнопка)
//имя стиля совпадает с именем картинки без расширения
Всего=Строка(табАдресов.Количество()); н=0;
Для каждого строкаАдреса Из табАдресов Цикл
н=н+1; Состояние("Вывод "+Строка(н)+" из "+Всего);
////ЭТО ПРИМЕР ВЫВОДА ТОГО ИЛИ ИНОГО МАРКЕРА В ЗАВИСИМОСТИ ОТ НЕКОЕГО ПАРАМЕТРА
//Если строкаАдреса.ДокументПродажи.суммаДокумента <1000 тогда
// имяСтиля = "BurG";
//ИначеЕсли строкаАдреса.ДокументПродажи.суммаДокумента <10000 тогда
// имяСтиля = "tr2_3_x";
//ИначеЕсли строкаАдреса.ДокументПродажи.суммаДокумента <20000 тогда
// имяСтиля = "kv3_4_x";
//ИначеЕсли строкаАдреса.ДокументПродажи.суммаДокумента <50000 тогда
// имяСтиля = "tr4_1_x";
//ИначеЕсли строкаАдреса.ДокументПродажи.суммаДокумента <100000 тогда
// имяСтиля = "kv5_2_x";
//Иначе
// имяСтиля = "cr6_3_x";
//конецЕсли;
УИД_Дока = Строка(н);
имяСтиля = "s"+Строка(строкаАдреса.ВидОбъекта.код);
Попытка
Если ЗначениеЗаполнено(строкаАдреса.КД) Тогда
ВызовФункции = "showAddressCoord(" + сокрЛП(строкаАдреса.КШ) + ", " + сокрЛП(строкаАдреса.КД) + ", '"+ сокрЛП(строкаАдреса.адрес) + "', " + имяСтиля + ", '" + сокрЛП(строкаАдреса.ВидОбъекта.наименование) + "')";
Иначе
ВызовФункции = "showAddress('" + сокрЛП(строкаАдреса.адрес) + "', '" + сокрЛП(строкаАдреса.адрес) + "', " + имяСтиля + ", '" + сокрЛП(строкаАдреса.ВидОбъекта.наименование) + "')";
КонецЕсли;
ЭлементыФормы.Карта.Document.parentWindow.eval(ВызовФункции);
исключение
Сообщить("Точка с адресом " + сокрЛП(строкаАдреса.адрес) + " не может быть отбражена на карте!" );
конецПопытки
КонецЦикла;
ТочкиНеСозданы = Ложь;
ЭлементыФормы.Карта.ПолучитьТекст();
КонецПроцедуры
//Изменение масштаба
Процедура Кнопка1Нажатие(Элемент)
если ЭлементыФормы.ВыборРегиона.значение = "Москва" Тогда
СтрокаКоординат = "37.64, 55.76, ";
ИначеЕсли ЭлементыФормы.ВыборРегиона.значение = "Тверь" Тогда
СтрокаКоординат = "35.90, 56.83, ";
ИначеЕсли ЭлементыФормы.ВыборРегиона.значение = "Балашиха" Тогда
СтрокаКоординат = "37.97, 55.82, ";
Иначе
СтрокаКоординат = "37.64, 55.76, ";
конецесли;
Если ВыборМасштаба = "" тогда
возврат;
конецесли;
числоМасштаба = Число(Лев(ВыборМасштаба, стрдлина(ВыборМасштаба)-1));
числоМасштаба = числоМасштаба + 5;
ВыборМасштаба = строка(числоМасштаба) + "%";
ТекущийМасштаб = Строка(Цел((числоМасштаба/125)*(20)+4));
если стрДлина(ТекущийМасштаб) =1 тогда
ТекущийМасштаб = "0" + ТекущийМасштаб;
конецесли;
ЭлементыФормы.Карта.Document.parentWindow.eval("mapRazmer(map," + СтрокаКоординат + ТекущийМасштаб + ")");
КонецПроцедуры
Пример обратного геокодирования - получение координат по адресу:
Код 1C v 8.х Процедура ПолучитьКоординаты() Экспорт
Яндекс = Новый HTTPСоединение("geocode-maps.yandex.ru",,,,,Истина);
ВременныйФайл = КаталогВременныхФайлов() + "Yandex_geocode_" + СокрЛП(Новый УникальныйИдентификатор);
Попытка
Яндекс.Получить("/1.x/?geocode=" + Адрес + "&results=1", ВременныйФайл);
Исключение
Сообщить("Ошибка при попытке геокодировать по яндексу адрес: " + Адрес);
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ВременныйФайл);
ПостроительDOM = Новый ПостроительDOM;
ДокументДОМ = ПостроительDOM.Прочитать(ЧтениеXML);
СписокText = ДокументДОМ.ПолучитьЭлементыПоИмени("text");
СписокPos = ДокументДОМ.ПолучитьЭлементыПоИмени("pos");
Если (СписокText.Количество() = 0) ИЛИ (СписокPos.Количество() = 0) Тогда
Возврат;
КонецЕсли;
Для ъ = 0 по СписокText.Количество()-1 Цикл
Координаты = СписокPos[Ъ].ТекстовоеСодержимое;
Разделитель = Найти(Координаты," ");
Широта = Число(Сред(Координаты, Разделитель + 1));
Долгота = Число(Лев(Координаты, Разделитель - 1));
Если Широта = 0 ИЛИ Долгота = 0 Тогда
Продолжить;
КонецЕсли;
КД = Долгота;
КШ = Широта;
КонецЦикла;
КонецПроцедуры
Обработка вырванная из конфигурации: YandexMap.rar
Можно ее использовать как макет для создания обработки под свои требования.
Пример автоматизации в котором это использовалось.
Категория:
Географическая схема Импорт в 1С из текстовых файлов (TXT, CSV) Не редко возникает необходимость загрузить в справочники или документы 1С данные из текстового файла. Приведенный пример внешней обработки позволит преобразовать текстовый файл с известным разделителем данных в поле табличного документа для последующей обработки уже внутри 1С:Предприятия. Обработка содержит функцию разбора строки на массив данных, настраиваемый разделитель строки текста на "столбцы", процедуру чтения данных из текстового файла.
Разбор строки в массив с использованием функций из конфигурации 1С
Для разложения строки в массив в конфигурация 1С:Бухгалтерия, 1С:Торговля и 1С:УПП имеется замечательная функция - Функция РазложитьСтрокуВМассивПодстрок(Знач Стр, Разделитель = ",") Экспорт. Функция "расщепляет" строку на подстроки, используя заданный разделитель. Разделитель может иметь любую длину. Если в качестве разделителя задан пробел, рядом стоящие пробелы считаются одним разделителем, а ведущие и хвостовые пробелы параметра "Стр" игнорируются. Подробнее можно прочесть внутри конфигурации - "Общие модули" -> "Общего назначения". Функция возвращает массив значений, элементы которого - подстроки.
Чтение текстового файла (txt) в 1С
Операцию импорта - экспорта текстовых файлов (формат тхт или csv, а также htm, html) очень удобно реализовать при помощи конструкции следующего вида:
1. Функция ПолучитьПотокЧтенияСтрок(Файл) - Назначение: Проверить наличие файла (функция Файл()), Создать текстовый документ (Новый ТекстовыйДокумент()), вызвать метод "Прочитать" для открытия потока чтения файла. Возвращает поток, готовый для чтения.
2. Процедура ЧтениеТХТФайла(Элемент) - Назначение: В цикле произвести последовательное чтение строк файла текстового документа, разбирая на массив колонок данных и добавляя значения массива в табличное поле;
Исходный код 1С функции создания текстового потока чтения файла ТХТ:
Код 1C v 8.х Функция ПолучитьПотокЧтенияСтрок(Файл)
Попытка
// Используется для доступа к параметрам файлов или каталогов.
ТекстовыйФайл = Новый Файл(Файл);
Если ТекстовыйФайл.Существует() = Ложь Тогда
Сообщить("Файла "+Файл+" не существует!");
Возврат Неопределено;
КонецЕсли;
// Текстовый документ предназначен для работы с текстами.
// Объект позволяет получать и сохранять текст в файле,
// работать со строками
ПотокЧтенияСтрок = Новый ТекстовыйДокумент();
ПотокЧтенияСтрок.Прочитать(ТекстовыйФайл);
Исключение
Сообщить("Файл не прочитан.", СтатусСообщения.Внимание);
Сообщить(ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
// Возвращает текст, извлеченный из файла
Возврат ПотокЧтенияСтрок;
КонецФункции // ПолучитьПотокЧтенияСтрок
// Исходный код функции загрузки строк в табличное поле:
Процедура ЧтениеТХТФайла(Элемент)
// Проверка на наличие имени файла
Если ПустаяСтрока(ИмяФайла) Тогда
Предупреждение("Для запуска обработки необходимо предварительно выбрать файл данных.");
Возврат;
КонецЕсли;
// Открыть файл, создать текстовый документ, прочитать
ПотокСтрок = ПолучитьПотокЧтенияСтрок(ИмяФайла);
// Очистить предыдущие значения
ТаблицаДокумента.Очистить();
ТаблицаДокумента.Колонки.Очистить();
// Создать колонки табличного документа
ТаблицаДокумента.Колонки.Добавить("Номер",,"Номер",5);
ТаблицаДокумента.Колонки.Добавить("Артикул",,"Артикул",11);
ТаблицаДокумента.Колонки.Добавить("Номенклатура",,"Номенклатура",25);
ТаблицаДокумента.Колонки.Добавить("Цена",,"Цена",6);
// Последовательное чтение строк текстового файла
КоличествоСтрок = ПотокСтрок.КоличествоСтрок();
Для Строка = 1 По КоличествоСтрок Цикл
// Обработка нажатия Ctrl + Break
ОбработкаПрерыванияПользователя();
// Чтение строки из файла тхт / csv
СтрокаИзФайла = ПотокСтрок.ПолучитьСтроку(Строка);
// Разбор строки в массив, используя в качествен символа-разделителя "|"
МассивСтрок = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(СтрокаИзФайла,"|");
// Добавить данные в табличную часть экранной формы
Стр=ТаблицаДокумента.Добавить();
Стр.Номер = Строка;
Стр.Артикул = МассивСтрок[0];
Стр.Номенклатура = МассивСтрок[1];
Стр.Цена = МассивСтрок[2];
// Отобразить информацию о ходе выполнения обработки
Состояние("Обработка строки файла : "
+ "строка " + Строка + " из " + КоличествоСтрок);
КонецЦикла;
// Отобразить результаты загрузки в форме элемента
ЭлементыФормы.ТаблицаДокумента.Значение = ТаблицаДокумента;
ЭлементыФормы.ТаблицаДокумента.СоздатьКолонки();
КонецПроцедуры // ЧтениеTXTФайла(Элемент)
В данном примере была произведена загрузка из текстового файла в следующем формате:
Код 7754|Процессор Atom 1.7|10,00
5054|Процессор AMD x64|8,99
7546|Мышь Microsoft|45,88
Категория:
XML, DBF, TXT, CSV Загрузить данные в 1с из текстового файла с разделителями В этой статье я расскажу, как загружать данные в 1с 8 из простейших текстовых файлов с разделителями. Обычно они имеют расширение csv (Comma-Separated Values). Т. е. название подразумевает, что в каждой строке такого текстового файла значения разделены запятой. Но на самом деле, запятую, в качестве разделителя, использовать не надёжно. Поэтому применяют другие разделители, которые в обычном тексте встречаются редко. Это могут быть символы «^», «~»,«|» и другие. Итак, наша задача состоит в том, чтобы загрузить имеющуюся в csv файле информацию в базу данных 1с. Например, в файле будут содержаться товары интернет - магазина. В качестве образца, я взял выгрузку из магазина на скрипте virtuemart. Посмотрим, как выглядит файл.
Привожу две первых строки из него:
Код ~product_sku~^~category_path~^~product_name~^~product_desc~
~20~^~Книги/Электронные книги~^~Amazon Kindle 4 Touch~^~<p>Популярная электронная книга с ч/б экраном 6", электронной бумагой E-Ink Pearl, разрешением 600x800 пикс. с 16 - ю оттенками серого.</p>~
Посмотрим на файл.
Первая строка служебная. В ней описан формат нашего файла. Т. е. в какой ячейке, что находится. Однако, имейте в виду, что такой строки может и не быть.
Ячейки образуются при помощи разделителя «^», а данные в ячейках обрамляются символом «~».
В любой конфигурации 1с есть иерархический справочник товаров. В него и будем загружать информацию.
Создадим внешнюю обработку. Добавим строковый реквизит «путьКФайлуЗагрузки» для хранения имени файла. Добавим на форму поле ввода, связанное с данным реквизитом. Включим в свойствах поля ввода кнопку выбора и создадим обработчик события «НачалоВыбора» и напишем в нём такой код:
Код 1C v 8.х Процедура путьКФайлуЗагрузкиНачалоВыбора(Элемент, СтандартнаяОбработка)
Режим = РежимДиалогаВыбораФайла.Открытие;
ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(Режим);
ДиалогОткрытияФайла.ПолноеИмяФайла = "";
Фильтр = "Comma separated file (*.csv)|*.csv";
ДиалогОткрытияФайла.Фильтр = Фильтр;
ДиалогОткрытияФайла.МножественныйВыбор = Ложь;
ДиалогОткрытияФайла.Заголовок = "Выберите файл";
Если ДиалогОткрытияФайла.Выбрать() Тогда
путьКФайлуЗагрузки = ДиалогОткрытияФайла.ПолноеИмяФайла;
КонецЕсли;
КонецПроцедуры
Т. о. мы организовали диалог для выбора файла в нашей обработке.
Хорошо. Теперь, для удобства и наглядности я предлагаю создать временную табличку, в которую мы загрузим текстовый файл, а уже после её заполнения - будем осуществлять загрузку в базу 1с. Для этого, на форму добавим табличное поле «табЗагрузки», с типом значения «ТаблицаЗначений» и командной панелью. В панели поместим кнопку «Заполнить» и создадим обработчик её нажатия «КоманднаяПанель1Заполнить». Также для элемента универсальности, добавим в обработку два строковых реквизита «символОграничения» и «разделительПолей». В них мы будем хранить «^», и «~». Можно в теле модуля формы осуществить их начальную инициализацию:
разделительПолей = "^";
символОграничения = "~";
Это позволит пользователю задать свои значения и при желании сохранить настройку, которая впоследствии не затрется нашей инициализацией.
Код 1C v 8.х Процедура КоманднаяПанель1Заполнить(Кнопка)
Если табЗагрузки.Количество() > 0 И Вопрос("Таблица будет очищена. Вы уверены?",РежимДиалогаВопрос.ДаНет)
= КодВозвратаДиалога.Нет Тогда
Возврат;
КонецЕсли;
ЗаполнитьТаблицу();
КонецПроцедуры
Процедура ЗаполнитьТаблицу()
текст = Новый ТекстовыйДокумент;
Попытка
//обязательно устанавливаем кодировку, в которой наш файл
текст.Прочитать(путьКФайлуЗагрузки,КодировкаТекста.UTF8);
Исключение
Сообщить("Не удалось прочитать файл: "
+ ОписаниеОшибки(),СтатусСообщения.ОченьВажное);
Возврат;
КонецПопытки;
табЗагрузки.Очистить();//очищаем таблицу
табЗагрузки.Колонки.Очистить();//удаляем колонки, так как их состав мог измениться
квоСтрок = текст.КоличествоСтрок();
Если Не квоСтрок > 0 Тогда
Сообщить("Файл пустой",СтатусСообщения.Внимание);
Возврат;
КонецЕсли;
//получаем первую строку с форматом файла
стрТекста = текст.ПолучитьСтроку(1);
//преобразуем строку в массив при помощи функции общего модуля, которая есть в типовых
//ниже я дам её код, на случай, если нет
масЗначСтр = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(стрТекста,разделительПолей);
//добавляем две служебные колонки
//для возможности отказаться от загрузки определенной строки
табЗагрузки.Колонки.Добавить("не_загружать",Новый ОписаниеТипов("Булево"),"Не загружать");
//для удобства вывода комментариев с указанием номера строки по ходу загрузки
табЗагрузки.Колонки.Добавить("номер_строки",Новый ОписаниеТипов("Число",
Новый КвалификаторыЧисла(10,0,ДопустимыйЗнак.Неотрицательный)),"Номер строки");
//формируем колонки нашей таблицы
Для каждого зн Из масЗначСтр Цикл
//убираем лишний символОграничения
значение = СтрЗаменить(зн,символОграничения,"");
кол = табЗагрузки.Колонки.Добавить(значение,Новый ОписаниеТипов("Строка"));
КонецЦикла;
//создаём колонки в табличном поле
ЭлементыФормы.табЗагрузки.СоздатьКолонки();
//начиная со второй строки читаем строки файла, раскладывая их в массив
Для номСтр = 2 По квоСтрок Цикл
стрТекста = текст.ПолучитьСтроку(номСтр);
масЗначСтр = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(стрТекста,разделительПолей);
//добавляем новую строку в таблицу
новСтр = табЗагрузки.Добавить();
новСтр.номер_строки = номСтр;
//начиная с третьей колонки производим установку значений в колонки
номЗнач = 2;
Для каждого зн Из масЗначСтр Цикл
новСтр[номЗнач] = СтрЗаменить(зн,символОграничения,"");
номЗнач = номЗнач + 1;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Функцию разложения строки с разделителями в массив можно разместить как в одном из общих модулей, так и непосредственно в обработке.
Код 1C v 8.х Функция РазложитьСтрокуВМассивПодстрок(Знач Стр, Разделитель = ",") Экспорт
МассивСтрок = Новый Массив();
Если Разделитель = " " Тогда
Стр = СокрЛП(Стр);
Пока Истина Цикл
Поз = Найти(Стр,Разделитель);
Если Поз=0 Тогда
МассивСтрок.Добавить(Стр);
Возврат МассивСтрок;
КонецЕсли;
МассивСтрок.Добавить(Лев(Стр,Поз-1));
Стр = СокрЛ(Сред(Стр,Поз));
КонецЦикла;
Иначе
ДлинаРазделителя = СтрДлина(Разделитель);
Пока Истина Цикл
Поз = Найти(Стр,Разделитель);
Если Поз=0 Тогда
МассивСтрок.Добавить(Стр);
Возврат МассивСтрок;
КонецЕсли;
МассивСтрок.Добавить(Лев(Стр,Поз-1));
Стр = Сред(Стр,Поз+ДлинаРазделителя);
КонецЦикла;
КонецЕсли;
КонецФункции
Отлично. В итоге, после заполнения, получим примерно такую картинку:
Теперь приступим непосредственно к загрузке товаров. Рядом с кнопкой «заполнить» добавим кнопку «загрузить» и добавим обработчик её нажатия «КоманднаяПанель1Загрузить», а также добавим реквизит «ПапкаЗагрузкиВыгрузкиТоваров» с типом вашего справочника товаров для опциональной их загрузки в определенную папку. Текст обработчика будет такой:
Код 1C v 8.х Процедура КоманднаяПанель1Загрузить(Кнопка)
Если Вопрос("Вы уверены, что хотите загрузить файл?", РежимДиалогаВопрос.ДаНет)
= КодВозвратаДиалога.Нет Тогда
Возврат;
КонецЕсли;
ВсегоСтрок = табЗагрузки.Количество();
номСтр = 1;
Для каждого стрТЗ Из табЗагрузки Цикл
Состояние("Обработано: " + Окр(номСтр * 100 / ВсегоСтрок) + "%");
номСтр = номСтр + 1;
ОбработкаПрерыванияПользователя();
//если пользователь установил не_загружать = Истина, пропускаем
Если стрТЗ.не_загружать Тогда
Продолжить;
КонецЕсли;
объект1С = вернутьТовар(стрТЗ);
Если объект1С = Неопределено Тогда
Возврат;
КонецЕсли;
Если Не ЗаписатьЭлементСпр(объект1С) Тогда
Сообщить("Загрузка прервана!",СтатусСообщения.ОченьВажное);
Возврат;
КонецЕсли;
//помечаем запись, как загруженную
стрТЗ.не_загружать = Истина;
КонецЦикла;
КонецПроцедуры
В приведенном коде две новые функции «вернутьТовар» и «ЗаписатьЭлементСпр». Вот их текст:
Код 1C v 8.х Функция вернутьТовар(стрТабФайла)
Артикул = стрТабФайла.product_sku;
Если Не ЗначениеЗаполнено(Артикул) Тогда
Сообщить("В строке " + стрТабФайла.номер_строки + " не заполнен product_sku",
СтатусСообщения.ОченьВажное);
Возврат Неопределено;
КонецЕсли;
Запрос = Новый Запрос("ВЫБРАТЬ
| Номенклатура.Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Артикул = &Артикул");
Запрос.УстановитьПараметр("Артикул",Артикул);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Возврат Выборка.Ссылка.ПолучитьОбъект();
Иначе
ЭтоНовый = Истина;
объект1С = Справочники.Номенклатура.СоздатьЭлемент();
объект1С.Артикул = Артикул;
объект1С.Наименование = стрТабФайла.product_name;
объект1С.Родитель = вернутьРодителяТовара(стрТабФайла.category_path);
Возврат объект1С;
КонецЕсли;
КонецФункции // вернутьТовар()
Функция ЗаписатьЭлементСпр(Спр)
Попытка
Спр.Записать();
Исключение
Сообщить("При записи элемента справочника " + Спр + " возникла ошибка: " + ОписаниеОшибки(),СтатусСообщения.ОченьВажное);
Возврат Ложь;
КонецПопытки;
Возврат Истина;
КонецФункции // ЗаписатьЭлементСпр()
И осталась последняя новая функция для обработки родителя товара вернутьРодителяТовара. Текст её смотрите ниже. Комментарии по тексту.
Код 1C v 8.х Функция вернутьРодителяТовара(стрКатегории)
//главный родитель - заполненная в обработке папка
Родитель = ПапкаЗагрузкиВыгрузкиТоваров;
//строку категории раскладываем в массив используя разделитель /
масРодителей = РазложитьСтрокуВМассивПодстрок(стрКатегории,"/");
Для каждого Род Из масРодителей Цикл
//если папку не находим, создаём и назначаем в качестве родителя
//следующей и т. д. В случае проблем выдаём прекращаем загрузку
РодСс = Справочники.Номенклатура.НайтиПоНаименованию(Род,Истина);
Если РодСс.Пустая() Тогда
НовРод = Справочники.Номенклатура.СоздатьГруппу();
НовРод.Наименование = Род;
НовРод.Родитель = Родитель;
Если Не ЗаписатьЭлементСпр(НовРод) Тогда
Возврат Неопределено;
КонецЕсли;
Родитель = НовРод.Ссылка;
Иначе
Родитель = РодСс;
КонецЕсли;
КонецЦикла;
Возврат Родитель;
КонецФункции //
Все. Конечно, в реальной жизни еще много чего нужно будет дописать, но не все сразу. Такой шаблон можно использовать как отправную точку.
Скачивать файлы может только зарегистрированный пользователь!
Успехов в разработке!
Источник Категория:
Текстовый документ Табличное поле ~ Заполнение данными, Ширина, Формат колонок, Подвал поля и Итоги? Код 1C v 8.х Запрос = Новый Запрос("ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ
| РеализацияТоваровУслугТовары.Ссылка КАК Ссылка,
| РеализацияТоваровУслугТовары.Ссылка.Номер,
| РеализацияТоваровУслугТовары.Ссылка.Дата,
| РеализацияТоваровУслугТовары.Ссылка.Контрагент,
| РеализацияТоваровУслугТовары.Ссылка.ТоннажДокумента КАК Тоннаж,
| РеализацияТоваровУслугТовары.Ссылка.СуммаДокумента КАК Сумма,
| 0 КАК ЕстьДопУслуги
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
|ГДЕ
| РеализацияТоваровУслугТовары.Ссылка.Доставка = &Ссылка
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| КомплектацияНоменклатурыКомплектующие.Ссылка.Ссылка,
| КомплектацияНоменклатурыКомплектующие.Ссылка.Номер,
| КомплектацияНоменклатурыКомплектующие.Ссылка.Дата,
| NULL,
| 0,
| 0,
| 0
|ИЗ
| Документ.КомплектацияНоменклатуры.Комплектующие КАК КомплектацияНоменклатурыКомплектующие
|ГДЕ
| КомплектацияНоменклатурыКомплектующие.Доставка = &Ссылка
|
|УПОРЯДОЧИТЬ ПО
| Ссылка
|АВТОУПОРЯДОЧИВАНИЕ");
Запрос.УстановитьПараметр("Ссылка", Ссылка);
ТабличноеПолеРеализаций = Запрос.Выполнить().Выгрузить();
ЭлементыФормы.ТабличноеПолеРеализаций.СоздатьКолонки();
ЭлементыФормы.ТабличноеПолеРеализаций.Колонки.ЕстьДопУслуги.Видимость = Ложь;
ЭлементыФормы.ТабличноеПолеРеализаций.Колонки.Тоннаж.ОтображатьИтогиВПодвале = Истина;
ЭлементыФормы.ТабличноеПолеРеализаций.Колонки.Сумма.ОтображатьИтогиВПодвале = Истина;
ЭлементыФормы.ТабличноеПолеРеализаций.Колонки.Тоннаж.ГоризонтальноеПоложениеВПодвале = ГоризонтальноеПоложение.Право;
ЭлементыФормы.ТабличноеПолеРеализаций.Колонки.Сумма.ГоризонтальноеПоложениеВПодвале = ГоризонтальноеПоложение.Право;
ЭлементыФормы.ТабличноеПолеРеализаций.Колонки.Тоннаж.ТекстПодвала = "" + Формат(ТабличноеПолеРеализаций.Итог("Тоннаж"), "ЧЦ=15; ЧДЦ=3");
ЭлементыФормы.ТабличноеПолеРеализаций.Колонки.Тоннаж.Ширина = 15;
ЭлементыФормы.ТабличноеПолеРеализаций.Колонки.Тоннаж.Формат = "ЧДЦ=3; ЧГ=3,0";
ЭлементыФормы.ТабличноеПолеРеализаций.Колонки.Сумма.Формат = "ЧДЦ=2; ЧГ=3,0";
Категория:
Работа с Формой (Диалог) и её элементами Как результат СКД в виде Табличного Документа разобрать и вывести в Дерево Значений Процедура получает из СКД результат в виде Табличного документа, парсит его, создает в Дереве на форме колонки и заполняет дерево данными результата СКД
Смысл в том, что СКД не может вывести результат в объект на форму, если он Таблица - выдает ошибку "Не поддерживается вывод таблиц, диаграмм и вложенных отчетов в универсальную коллекцию значений".
Поэтому я выгружаю СКД в ТабличныйДокумент и вытаскиваю данные уже из него, далее строю и заполняю Дерево на форме
Код 1C v 8.х Процедура ЗаполнитьДерево()
ДеревоЗначений.Строки.Очистить();
КолРазмеров = 0;
СхемаКомпоновкиДанных = ПолучитьМакет("Схема");
Настройки = СхемаКомпоновкиДанных.НастройкиПоУмолчанию;
Для Каждого ЭлементОтбора Из ПостроительОтчета.Отбор Цикл
Если Не ЭлементОтбора.Использование Тогда
Продолжить;
КонецЕсли;
ВидСравненияВОтборе = мСоответствиеВидовСравнения.Получить(ЭлементОтбора.ВидСравнения);
Если ВидСравненияВОтборе = Неопределено Тогда
Продолжить;
КонецЕсли;
Если Лев(ЭлементОтбора.ПутьКДанным, 8) = "Свойство" Тогда
ИмяПоля = "Номенклатура.["+мСоответствиеНазначений[ЭлементОтбора.Представление]+" (свойство)]";
ИначеЕсли Лев(ЭлементОтбора.ПутьКДанным, 9) = "Категория" Тогда
ИмяПоля = "Номенклатура.["+мСоответствиеНазначений[ЭлементОтбора.Представление]+" (категория)]";
Иначе
ИмяПоля = ЭлементОтбора.ПутьКДанным;
КонецЕсли;
ПолеОтбора = Новый ПолеКомпоновкиДанных(ИмяПоля);
Отбор = Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
Отбор.ЛевоеЗначение = ПолеОтбора;
Отбор.Использование = Истина;
Отбор.ВидСравнения = ВидСравненияВОтборе;
Отбор.ПравоеЗначение = ЭлементОтбора.Значение;
КонецЦикла;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки,, Тип("ГенераторМакетаКомпоновкиДанных"));
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки,, ДанныеРасшифровки);
ТабличныйДокумент = Новый ТабличныйДокумент;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабличныйДокумент);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных, Истина);
//ТабличныйДокумент.Показать();
КолДанных = 5; //кол. данных в колонке таблицы СКД
СоздатьДерево(ТабличныйДокумент, КолДанных);
СтКол = Новый Структура;
СтКол.Вставить("Ном", 1);
СтКол.Вставить("Дат1", 2);
СтКол.Вставить("Дат2", 3);
СтКол.Вставить("Прих", 4);
СтКол.Вставить("Реал", 5);
СтКол.Вставить("Возв", 6);
СтКол.Вставить("Остат", 7);
СтКол.Вставить("ВПути", 8);
СтрНом = Неопределено;
СтрДерева = Неопределено;
Для i=3 По ТабличныйДокумент.ВысотаТаблицы Цикл
ПерваяКолонка = ПолучитьЗначениеРасшифровки(ТабличныйДокумент, i, СтКол.Ном);
Если ТипЗнч(ПерваяКолонка) = Тип("СправочникСсылка.Номенклатура") Тогда
Если СтрНом Неопределено Тогда
СтрНом.Строки.Сортировать("Продажи УБЫВ");
СтрНом.ОстатокМагазин = СтрНом.Строки.Итог("ОстатокМагазин");
СтрНом.ОстатокСклад = СтрНом.Строки.Итог("ОстатокСклад");
КонецЕсли;
СтрНом = ДеревоЗначений.Строки.Добавить();
СтрДерева = СтрНом;
ИначеЕсли ТипЗнч(ПерваяКолонка) = Тип("СправочникСсылка.Склады") Тогда
СтрДерева = СтрНом.Строки.Добавить();
Дат1 = Формат(ПолучитьЗначениеРасшифровки(ТабличныйДокумент, i, СтКол.Дат1), "ДФ=dd.MM.yy");
Дат2 = Формат(ПолучитьЗначениеРасшифровки(ТабличныйДокумент, i, СтКол.Дат2), "ДФ=dd.MM.yy");
СтрДерева.Период = "" + Дат1 + " - " + Дат2;
Иначе
Продолжить;
КонецЕсли;
СтрДерева.Номенклатура = ПерваяКолонка;
СтрДерева.Остаток = ПолучитьЗначениеРасшифровки(ТабличныйДокумент, i, СтКол.Остат, Истина);
СтрДерева.Приход = ПолучитьЗначениеРасшифровки(ТабличныйДокумент, i, СтКол.Прих, Истина);
СтрДерева.Продажи = ПолучитьЗначениеРасшифровки(ТабличныйДокумент, i, СтКол.Реал, Истина);
СтрДерева.Возврат = ПолучитьЗначениеРасшифровки(ТабличныйДокумент, i, СтКол.Возв, Истина);
Если ЗначениеЗаполнено(СтрДерева.Родитель) Тогда
Если ПерваяКолонка.ТипСклада = Перечисления.ТипыСкладов.ТорговыйЗал Тогда СтрДерева.ОстатокМагазин = СтрДерева.Остаток;
Иначе СтрДерева.ОстатокСклад = СтрДерева.Остаток;
КонецЕсли;
Попытка СтрДерева.ПроцентПродаж = СтрДерева.Продажи * 100 / СтрДерева.Родитель.Продажи;
Исключение СтрДерева.ПроцентПродаж = "-";
КонецПопытки;
Иначе
СтрДерева.ПроцентПродаж = "100%";
КонецЕсли;
Для j=1 По КолРазмеров Цикл
СтрДерева["Ост" + j] = ПолучитьЗначениеРасшифровки(ТабличныйДокумент, i, 3 + КолДанных * j + 4, Истина);
СтрДерева["Пут" + j] = ПолучитьЗначениеРасшифровки(ТабличныйДокумент, i, 3 + КолДанных * j + 5, Истина);
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Процедура СоздатьДерево(ТабличныйДокумент, КолДанных)
КЧ = Новый КвалификаторыЧисла(10, 0);
Массив = Новый Массив;
Массив.Добавить(Тип("Число"));
ОписаниеТиповЧ = Новый ОписаниеТипов(Массив,,,КЧ);
Ном = 3 + КолДанных + 1; //колонки в таблич. документе (Ном/Склад, перв. дата, посл. дата)
КолРазмеров = (ТабличныйДокумент.ШиринаТаблицы - Ном-1) / КолДанных + 1;
Для i=1 По КолРазмеров Цикл
Размер = ПолучитьЗначениеРасшифровки(ТабличныйДокумент, 1, Ном, Истина, Ложь);
Ном = Ном + КолДанных;
Попытка
ДеревоЗначений.Колонки.Добавить("Ост" + i, ОписаниеТиповЧ, Размер, 5);
ДеревоЗначений.Колонки.Добавить("Пут" + i, ОписаниеТиповЧ, "Путь", 5);
ДеревоЗначений.Колонки.Добавить("Пер" + i, ОписаниеТиповЧ, "Пер", 5);
Исключение
КонецПопытки;
КонецЦикла;
ЭтаФорма.ЭлементыФормы.ДеревоЗначений.Значение = ДеревоЗначений;
ЭтаФорма.ЭлементыФормы.ДеревоЗначений.СоздатьКолонки();
i=1; НомерРазмера=1;
Для Каждого Кол Из ЭтаФорма.ЭлементыФормы.ДеревоЗначений.Колонки Цикл
Кол.ТолькоПросмотр = Истина;
Если i = (НомерРазмера + 8 + 1) Тогда
Кол.Положение = ПоложениеКолонки.НоваяКолонка;
ИначеЕсли i = (НомерРазмера + 8 + 2) Тогда
Кол.Положение = ПоложениеКолонки.НаСледующейСтроке;
ИначеЕсли i = (НомерРазмера + 8 + 3) Тогда
Кол.Положение = ПоложениеКолонки.ВТойЖеКолонке;
Кол.ТолькоПросмотр = Ложь;
НомерРазмера = НомерРазмера + 3;
КонецЕсли;
Если i=1 Тогда
Кол.Ширина = 20;
Иначе
Если i=2 Тогда Кол.Ширина = 11;
ИначеЕсли i9 Тогда Кол.Ширина = 7;
Иначе Кол.Ширина = 5;
КонецЕсли;
Кол.ИзменениеРазмера = ИзменениеРазмераКолонки.НеИзменять;
КонецЕсли;
i=i+1;
КонецЦикла;
КонецПроцедуры
Автор:
Абазин Антон Категория:
Схема Компоновки Данных Табличное поле ~ Отображение ИТОГа в Подвале таблицы Код 1C v 8.х ТПТЧ = КакаяТоТЗсДанными;
ЭлементыФормы.ТПТЧ.СоздатьКолонки();
//Пропишем отображение Итога, ПРЕДВАРИТЕЛЬНО - ПОСТАВИВ ГАЛОЧКУ ОТОБРАЖЕНИЯ ПОДВАЛА
Для Каждого Кол из ЭлементыФормы.ТПТЧ.Колонки Цикл
Попытка
Кол.ОтображатьИтогиВПодвале = Истина;
Кол.ГоризонтальноеПоложениеВПодвале = ГоризонтальноеПоложение.Право;
Исключение КонецПопытки;
КонецЦикла;
Категория:
Работа с Формой (Диалог) и её элементами Форма ~ Программное добавление элементов на форму ЭлементыФормы (Controls) . Добавить (Add) - Добавляет элемент управления на форму.
Синтаксис: Код 1C v 8.х Добавить(<Тип>, <Имя>, <Видимость>, <ПоместитьНа>)
Параметры:
<Тип> (обязательный)
Тип: Тип. Тип добавляемого элемента управления:
Индикатор; ПолеКалендаря; Кнопка; КоманднаяПанель; Надпись; Панель; Переключатель; ПолеТабличногоДокумента; ПолеHTMLДокумента; ПолеТекстовогоДокумента; ПолеВвода; ПолеВыбора; ПолеСписка; ПолеКартинки; ПолосаРегулирования; Разделитель; РамкаГруппы; ТабличноеПоле; Флажок; ПолеГрафическойСхемы; ПолеГеографическойСхемы.
<Имя> (обязательный)
Тип: Строка. Имя создаваемого элемента управления. Имя должно быть указано в соответсвии с правилами написания имен системы 1С:Предприятие 8. В противном случае выполнение метода вызовет исключение.
<Видимость> (необязательный)
Тип: Булево. Определяет, создавать новый элемент управления формы видимым или нет. Истина - элемент создается видимым.
Значение по умолчанию: Истина
<ПоместитьНа> (необязательный)
Тип: Панель; ПолеТабличногоДокумента. Определяет, какой панели формы или какому табличному документу принадлежит создаваемый элемент. Если указана панель, то добавляемый элемент размещается на текущей странице панели. Если не указан, создаваемый элемент будет принадлежать непосредственно форме.
Код 1C v 8.х
// Расположим на странице табличное поле
ПолеРегистра = ЭлементыФормы.Добавить(Тип("ТабличноеПоле"),
СтрокаТаблицы.Имя,
Истина,
ЭлементыФормы.ОсновнаяПанель);
ПолеРегистра.Данные = "ДокументОбъект.Движения." + СтрокаТаблицы.Имя;
Если НЕ ЭтоНовый() Тогда
ПолеРегистра.Значение.Прочитать();
КонецЕсли;
ПолеРегистра.Верх = 30;
ПолеРегистра.Лево = 6;
ПолеРегистра.Ширина = ЭлементыФормы.ОсновнаяПанель.Ширина - 14;
ПолеРегистра.Высота = ЭлементыФормы.ОсновнаяПанель.Высота - 56;
ПолеРегистра.ТолькоПросмотр = Ложь;
ПолеРегистра.ИзменятьПорядокСтрок = Истина;
ПолеРегистра.ИзменятьСоставСтрок = Истина;
ПолеРегистра.УстановитьПривязку(ГраницаЭлементаУправления.Верх,
КоманднаяПанельРегистра,
ГраницаЭлементаУправления.Низ);
ПолеРегистра.УстановитьПривязку(ГраницаЭлементаУправления.Низ,
ЭлементыФормы.ОсновнаяПанель,
ГраницаЭлементаУправления.Низ);
ПолеРегистра.УстановитьПривязку(ГраницаЭлементаУправления.Право,
ЭлементыФормы.ОсновнаяПанель,
ГраницаЭлементаУправления.Право);
ПолеРегистра.СоздатьКолонки();
Если Метаданные.РегистрыНакопления[СтрокаТаблицы.Имя].ВидРегистра = Метаданные.СвойстваОбъектов.ВидРегистраНакопления.Остатки Тогда
КолонкаВидДвижения = ПолеРегистра.Колонки.Вставить(1, "Вид движения");
КолонкаВидДвижения.Имя = "ВидДвиженияРегистраНакопления";
КолонкаВидДвижения.УстановитьЭлементУправления(Тип("ПолеВвода"));
КолонкаВидДвижения.Данные = "ВидДвижения";
КолонкаВидДвижения.ЭлементУправления.КнопкаВыбора = Истина;
КолонкаВидДвижения.ЭлементУправления.ВыбиратьТип = Ложь;
КонецЕсли;
ПолеРегистра.Колонки.Регистратор.Видимость = Ложь;
ПолеРегистра.Колонки.Период.Видимость = Ложь;
ПолеРегистра.Колонки.НомерСтроки.Видимость = Ложь;
// Поле ввода
ПолеВвода = ЭлементыФормы.Добавить(Тип("ПолеВвода"), "ПолеВвода", Истина);
ПолеВвода.Верх = Надпись.Верх + Надпись.Высота + 5;
ПолеВвода.Лево = ЭлементыФормы.Переключатель1.Лево;
ПолеВвода.Ширина = ЭлементыФормы.Переключатель1.Ширина;
ПолеВвода.Высота = ЭлементыФормы.Переключатель1.Высота;
ПолеВвода.Доступность = Ложь;
// установка привязок
ПолеВвода.УстановитьПривязку(ГраницаЭлементаУправления.Низ, ПолеВвода, ГраницаЭлементаУправления.Верх);
ПолеВвода.УстановитьПривязку(ГраницаЭлементаУправления.Лево, ЭтаФорма.Панель, ГраницаЭлементаУправления.Лево);
ПолеВвода.УстановитьПривязку(ГраницаЭлементаУправления.Право, ЭтаФорма.Панель, ГраницаЭлементаУправления.Право);
//Надпись и поле ввода
ЭлементНадпись = ЭлементыФормы.Добавить(Тип("Надпись"), "Надпись"+ИмяЭлемента, Истина, ЭлементыФормы.ПанельПодбор);
ЭлементНадпись.Заголовок = Синоним + ":";
ЭлементНадпись.Лево = 6;
ЭлементНадпись.Верх = ВерхЭлемента + 6;
ЭлементНадпись.Высота = 19;
ЭлементНадпись.Ширина = 160;
ЭлементНадпись.ЦветФона = ЦветаСтиля.ФонЭпицентра;
ЭлементПолеВвода = ЭлементыФормы.Добавить(Тип("ПолеВвода"), ИмяЭлемента, Истина, ЭлементыФормы.ПанельПодбор);
ЭлементПолеВвода.ТипЗначения = Параметр.Тип;
ЭлементПолеВвода.Верх = ЭлементНадпись.Верх;
ЭлементПолеВвода.Лево = ЭлементНадпись.Лево + ЭлементНадпись.Ширина + 6;
ЭлементПолеВвода.Высота = ЭлементНадпись.Высота;
Если ЭлементПолеВвода.ТипЗначения.СодержитТип(Тип("Дата")) Тогда
ЭлементПолеВвода.Ширина = 80;
Иначе
ЭлементПолеВвода.Ширина = 200;
КонецЕсли;
//Надпись и Поле Выбора
ИмяЭлемента = " Подписывающий";
ЭлементНадпись = ЭлементыФормы.Добавить(Тип("Надпись"), "Надпись"+ИмяЭлемента, Истина,);
ЭлементНадпись.Заголовок = ИмяЭлемента + ":";
ЭлементНадпись.Лево = 250;
ЭлементНадпись.Верх = 33;
ЭлементНадпись.Высота = 19;
ЭлементНадпись.Ширина = 160;
ЭлементНадпись.ЦветФона = ЦветаСтиля.ЦветФонаФормы;
ЭлементПолеВвода = ЭлементыФормы.Добавить(Тип("ПолеВыбора""), ИмяЭлемента, Истина,);
ЭлементПолеВвода.Данные = Подписывающий;
//ЭлементПолеВвода.ТипЗначения = Новый ОписаниеТипов("СправочникСсылка.СотрудникиОрганизаций");
ЭлементПолеВвода.Верх = ЭлементНадпись.Верх;
ЭлементПолеВвода.Лево = ЭлементНадпись.Лево + ЭлементНадпись.Ширина + 6;
ЭлементПолеВвода.Высота = ЭлементНадпись.Высота;
ЭлементПолеВвода.Ширина = 200;
Категория:
Работа с Формой (Диалог) и её элементами Примеры работы с Деревом значений в УП Так как работа с ДеревомЗначений и ТаблицейЗначений в данном контексте практически не отличается, в примере будет использоваться ДеревоЗначений, все тоже самое за исключением иерархии применимо и к ТаблицеЗначений. Как известно, в
платформе 1С 8.1 не составляло никакого труда связать дерево значений с табличным полем на форме, единственное что при этом нужно было не забыть так это СоздатьКолонки() .
В управляемом приложении 1С 8.2 сделать это не так просто как кажется на первый взгляд.
Обращаю внимание, что
ДеревоЗначений доступно только на сервере, в толстом клиенте и внешнем соединение. В данных самой управляемой формы для моделирования дерева используется тип ДанныеФормыДерево. Для преобразования ДеревоЗначений <-> ДанныеФормыДерево используются методы управляемой формы ЗначениеВРеквизитФормы() и РеквизитФормыВЗначение(). Для непосредственного отображения дерева используется элемент формы типа ТаблицаФормы связанный через реквизит ПутьКДанным с реквизитом формы типа ДанныеФормыДерево. Если Вам не очень понятна вышеописанная связь объектов, не огорчайтесь, ниже рассмотрим практический пример и все встанет на свои места.
Задача: Имеется дерево значений, необходимо отобразить его на управляемой форме.
Создаем новую внешнюю обработку (
Скачивать файлы может только зарегистрированный пользователь! ), добавляем управляемую форму и создаем обработчик ПриСозданииНаСервере(). Никаких реквизитов и элементов “вручную” не добавляем, будем делать это программно.
Код 1C v 8.2 УП &НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Создание и заполнение "обычного" объекта прикладного типа ДеревоЗначений,
// который будет отображен на управляемой форме
ДеревоОбъект = Новый ДеревоЗначений;
ДеревоОбъект.Колонки.Добавить("Узел", Новый ОписаниеТипов("Строка"));
Для к1 = 1 По 3 Цикл
СтрокаУ1 = ДеревоОбъект.Строки.Добавить();
СтрокаУ1.Узел = "Узел"+к1;
Для к2 = 1 По 3 Цикл
СтрокаУ2 = СтрокаУ1.Строки.Добавить();
СтрокаУ2.Узел = СтрокаУ1.Узел+к2;
Для к3 = 1 По 3 Цикл
СтрокаУ3 = СтрокаУ2.Строки.Добавить();
СтрокаУ3.Узел = СтрокаУ2.Узел+к3;
КонецЦикла;
КонецЦикла;
КонецЦикла;
// Создание Реквизита формы типа ДанныеФормыДерево
МассивДобавляемыхРеквизитов = Новый Массив;
МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы("Дерево",
Новый ОписаниеТипов("ДеревоЗначений")));
Для Каждого Колонка Из ДеревоОбъект.Колонки Цикл
МассивДобавляемыхРеквизитов.Добавить(
Новый РеквизитФормы(Колонка.Имя, Колонка.ТипЗначения, "Дерево"));
КонецЦикла;
ИзменитьРеквизиты(МассивДобавляемыхРеквизитов);
// Преобразование объекта прикладного типа ДеревоЗначений
// в реквизит управляемой формы (данные формы)
ЗначениеВРеквизитФормы(ДеревоОбъект, "Дерево");
// Создание элемента формы типа ТаблицаФормы для отображения дерева
ЭлементДерево = Элементы.Добавить("Дерево", Тип("ТаблицаФормы"));
ЭлементДерево.ПутьКДанным = "Дерево";
ЭлементДерево.Отображение = ОтображениеТаблицы.Дерево;
Для Каждого Колонка Из ДеревоОбъект.Колонки Цикл
НовыйЭлемент = Элементы.Добавить(Колонка.Имя, Тип("ПолеФормы"),
ЭлементДерево);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ПутьКДанным = "Дерево." + Колонка.Имя;
КонецЦикла;
КонецПроцедуры
Механизм Drag and D_rop (или проще говоря “Перетаскивания”) для ДереваЗначений расположенного на управляемой форме управляемого приложения
Основная сложность реализации механизма перетаскивания заключается в том, что у строки ДереваЗначений платформа не позволяет просто изменить родителя, т.е. переподчинить строку. Единственный способ это сделать – создать новую строку вместе со всеми подчиненными строками, т.е. полностью скопировать всю ветку дерева вместе со всей иерархией и подчинить ее требуемой строке-родителю, после чего удалить исходную ветку. Данная задача распадается на две подзадачи:
1). Перед перетаскиванием необходимо проверить корректность данной операции, узел дерева нельзя переносить в узлы подчиненные ему самому, т.е. родительский узел нельзя переносить в дочерние, т.к. это приведет к “бесконечной рекурсии” и “падению” платформы. Это реализуется с помощью обработчика события ЭлементДеревоПроверкаПеретаскивания(…)
2). Если перетаскивание возможно, то при помощи обработчика ЭлементДеревоПеретаскивание(…) запускается рекурсивная функция, которая создает новую ветку дерева, подчиненную требуемому родителю, а исходную удаляет.
Обращаю особое внимание на то, что в платформе 8.2 реализован механизм множественного выбора элементов, поэтому вышеуказанные операции необходимо произвести для всех выбранных пользователем элементов. (
Скачивать файлы может только зарегистрированный пользователь! )
Код 1C v 8.2 УП &НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Создание и заполнение "обычного" объекта прикладного типа ДеревоЗначений,
// который будет отображен на управляемой форме
// Здесь необходимо расположить код из предыдущей статьи
// «Работа с деревом значений и таблицей значений. Часть I (Основы)»
// .....................................................
// Добавим обработчики и установим свойства
ЭлементДерево.МножественныйВыбор=Истина;
ЭлементДерево.РазрешитьПеретаскивание=Истина;
ЭлементДерево.РазрешитьНачалоПеретаскивания=Истина;
ЭлементДерево.УстановитьДействие("ПроверкаПеретаскивания",
"ЭлементДеревоПроверкаПеретаскивания");
ЭлементДерево.УстановитьДействие("Перетаскивание",
"ЭлементДеревоПеретаскивание");
КонецПроцедуры
&НаКлиенте
Функция ПроверитьВозможностьПереноса(ПереносимыйЭлемент, Знач НовыйРодитель)
Пока НЕ НовыйРодитель = Неопределено Цикл
Если ПереносимыйЭлемент = НовыйРодитель Тогда
Возврат Ложь;
КонецЕсли;
НовыйРодитель = НовыйРодитель.ПолучитьРодителя();
КонецЦикла;
Возврат Истина;
КонецФункции
&НаКлиенте
Функция СкопироватьСтрокуДерева(РеквизитДерево, Приемник, Источник)
Перем НоваяСтрока, ОбратныйИндекс, КолПодчиненныхСтрок;
// Источник может быть уже перенесен
// Это происходит если выделены несколько элементов
// одной и той же ветви дерева на разных уровнях иерархии
Если Источник = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Если Приемник = Неопределено Тогда
// Добавляем в корень
НоваяСтрока = РеквизитДерево.ПолучитьЭлементы().Добавить();
Иначе
НоваяСтрока = Приемник.ПолучитьЭлементы().Добавить();
КонецЕсли;
ЗаполнитьЗначенияСвойств(НоваяСтрока, Источник);
КолПодчиненныхСтрок = Источник.ПолучитьЭлементы().Количество();
Для ОбратныйИндекс = 1 По КолПодчиненныхСтрок Цикл
ПодчиненнаяСтрока = Источник.ПолучитьЭлементы()
[КолПодчиненныхСтрок - ОбратныйИндекс];
СкопироватьСтрокуДерева(РеквизитДерево, НоваяСтрока, ПодчиненнаяСтрока);
КонецЦикла;
Если Источник.ПолучитьРодителя() = Неопределено Тогда
РеквизитДерево.ПолучитьЭлементы().Удалить(Источник);
Иначе
Источник.ПолучитьРодителя().ПолучитьЭлементы().Удалить(Источник);
КонецЕсли;
Возврат НоваяСтрока;
КонецФункции
&НаКлиенте
Процедура ЭлементДеревоПроверкаПеретаскивания(Элемент, ПараметрыПеретаскивания,
СтандартнаяОбработка, Строка, Поле)
// Узел нельзя переносить в узлы подчиненные ему самому
// т.е. родительский узел нельзя переносить в дочерние.
// Проверим это условие для всех выделенных элементов
СтандартнаяОбработка = Ложь;
РеквизитДерево = ЭтаФорма["Дерево"];
ИДНовыйРодитель = Строка;
// Если НовыйРодитель = Неопределено => Корень дерева
НовыйРодитель = ?(ИДНовыйРодитель = Неопределено, Неопределено,
РеквизитДерево.НайтиПоИдентификатору(ИДНовыйРодитель));
МассивИДПереносимыхЭлементов = ПараметрыПеретаскивания.Значение;
Для каждого ИДПереносимыйЭлемент из МассивИДПереносимыхЭлементов Цикл
ПереносимыйЭлемент = РеквизитДерево.НайтиПоИдентификатору(
ИДПереносимыйЭлемент);
Если НЕ ПроверитьВозможностьПереноса(ПереносимыйЭлемент,
НовыйРодитель) Тогда
ПараметрыПеретаскивания.Действие=ДействиеПеретаскивания.Отмена;
Прервать;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура ЭлементДеревоПеретаскивание(Элемент, ПараметрыПеретаскивания,
СтандартнаяОбработка, Строка, Поле)
СтандартнаяОбработка=Ложь;
РеквизитДерево = ЭтаФорма["Дерево"];
ИДПриемник = Строка;
// Если ИДПриемник = Неопределено => Корень дерева
Приемник = ?(ИДПриемник = Неопределено, Неопределено,
РеквизитДерево.НайтиПоИдентификатору(ИДПриемник));
МассивИДИсточник = ПараметрыПеретаскивания.Значение;
Для Каждого ИДИсточник Из МассивИДИсточник Цикл
Источник = РеквизитДерево.НайтиПоИдентификатору(ИДИсточник);
НоваяСтрока = СкопироватьСтрокуДерева(РеквизитДерево, Приемник, Источник);
// Производится копирование в корень
// Для "красоты" развернем вновь созданную ветвь
Если Приемник = Неопределено и НоваяСтрока<>Неопределено Тогда
Элементы["Дерево"].Развернуть(НоваяСтрока.ПолучитьИдентификатор(),
Истина);
КонецЕсли;
КонецЦикла;
// Для "красоты" развернем ветвь-родителя
Если НЕ Приемник = Неопределено Тогда
Элементы["Дерево"].Развернуть(ИДПриемник, Истина);
КонецЕсли;
КонецПроцедуры
Реализовать трехпозиционный флажок в ДеревеЗначений на управляемой форме
который работает по следующему алгоритму:
* Если у элемента ДереваЗначений нет подчиненных элементов, то флажок может быть либо “включен”, либо “выключен”.
* Если у элемента есть подчиненные, то флажок “включен”, если ВКЛЮЧЕНЫ флажки у ВСЕХ подчиненных элементов, “выключен” если ВЫКЛЮЧЕНЫ флажки у ВСЕХ подчиненных элементов.
Если у некоторых подчиненных элементов флажки включены, а у некоторых выключены, то флажок родительского элемента имеет значение “неопределенно”.
* При включении флажка у родительского элемента, включаются флажки ВСЕХ подчиненных, при выключении флажка у родительского элемента, выключаются флажки ВСЕХ подчиненных.
Возьмем из первой статьи процедуру построения дерева значений и доработаем ее, добавив в дерево еще одну колонку, которая будет содержать элемент управления флажок и реализуем для него обработчик события “ПриИзменении”. Весь алгоритм сводится к обработке изменения флажка: у всех подчиненных элементов необходимо включить/выключить флажки в зависимости от состояния флажка текущего элемента, а у всех родителей текущего элемента (которые расположены на верхних уровнях иерархии) проставить флажки в состояния “включен”/”выключен”/”неопределенно” в соответствии с вышеописанным алгоритмом. (
Скачивать файлы может только зарегистрированный пользователь! )
Код 1C v 8.2 УП &НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Создание и заполнение "обычного" объекта прикладного типа ДеревоЗначений,
// который будет отображен на управляемой форме
ДеревоОбъект = Новый ДеревоЗначений;
ДеревоОбъект.Колонки.Добавить("Узел", Новый ОписаниеТипов("Строка"));
ДеревоОбъект.Колонки.Добавить("Пометка", Новый ОписаниеТипов("Число"));
Для к1 = 1 По 3 Цикл
СтрокаУ1 = ДеревоОбъект.Строки.Добавить();
СтрокаУ1.Узел = "Узел"+к1;
Для к2 = 1 По 3 Цикл
СтрокаУ2 = СтрокаУ1.Строки.Добавить();
СтрокаУ2.Узел = СтрокаУ1.Узел+к2;
Для к3 = 1 По 3 Цикл
СтрокаУ3 = СтрокаУ2.Строки.Добавить();
СтрокаУ3.Узел = СтрокаУ2.Узел+к3;
КонецЦикла;
КонецЦикла;
КонецЦикла;
// Создание Реквизита формы типа ДанныеФормыДерево
МассивДобавляемыхРеквизитов = Новый Массив;
МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы("Дерево",
Новый ОписаниеТипов("ДеревоЗначений")));
Для Каждого Колонка Из ДеревоОбъект.Колонки Цикл
МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы(Колонка.Имя,
Колонка.ТипЗначения, "Дерево"));
КонецЦикла;
ИзменитьРеквизиты(МассивДобавляемыхРеквизитов);
// Преобразование объекта прикладного типа ДеревоЗначений
// в реквизит управляемой формы (данные формы)
ЗначениеВРеквизитФормы(ДеревоОбъект, "Дерево");
// Создание элемента формы типа ТаблицаФормы для отображения дерева
ЭлементДерево = Элементы.Добавить("Дерево", Тип("ТаблицаФормы"));
ЭлементДерево.ПутьКДанным = "Дерево";
ЭлементДерево.Отображение = ОтображениеТаблицы.Дерево;
Для Каждого Колонка Из ДеревоОбъект.Колонки Цикл
НовыйЭлемент = Элементы.Добавить(Колонка.Имя, Тип("ПолеФормы"),
ЭлементДерево);
НовыйЭлемент.ПутьКДанным = "Дерево." + Колонка.Имя;
Если НЕ Колонка.Имя = "Пометка" Тогда
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
Иначе
НовыйЭлемент.Вид = ВидПоляФормы.ПолеФлажка;
НовыйЭлемент.ТриСостояния = Истина;
НовыйЭлемент.УстановитьДействие("ПриИзменении",
"ФлажокПриИзменении");
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура ФлажокПриИзменении(Элемент)
ИДТекущейСтроки = Элементы["Дерево"].ТекущаяСтрока;
Если ИДТекущейСтроки <> Неопределено Тогда
ЭлементКоллекции = ЭтаФорма["Дерево"].НайтиПоИдентификатору(
ИДТекущейСтроки);
Если ЭлементКоллекции.Пометка = 2 Тогда
ЭлементКоллекции.Пометка = 0;
КонецЕсли;
УстановкаФлажков(ЭлементКоллекции, ЭлементКоллекции.Пометка);
Родитель = ЭлементКоллекции.ПолучитьРодителя();
Пока Родитель <> Неопределено Цикл
Родитель.Пометка = ?(УстановленноДляВсех(ЭлементКоллекции),
ЭлементКоллекции.Пометка, 2);
ЭлементКоллекции = Родитель;
Родитель = ЭлементКоллекции.ПолучитьРодителя();
КонецЦикла;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура УстановкаФлажков(ЭлементКоллекции, ЗначениеПометки)
ПодчинЭлементы = ЭлементКоллекции.ПолучитьЭлементы();
Для Каждого ТекЭлемент Из ПодчинЭлементы Цикл
ТекЭлемент.Пометка = ЗначениеПометки;
УстановкаФлажков(ТекЭлемент, ТекЭлемент.Пометка);
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Функция УстановленноДляВсех(ЭлементКоллекции)
СоседниеЭлементы =
ЭлементКоллекции.ПолучитьРодителя().ПолучитьЭлементы();
Для Каждого ТекЭлемент Из СоседниеЭлементы Цикл
Если ТекЭлемент.Пометка <> ЭлементКоллекции.Пометка Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Возврат Истина;
КонецФункции
Источник Категория:
Работа с Деревом Значений Табличное поле ~ Как реализовать в дереве значений флажок с тремя состояниями? 8.2 УП
Необходимо реализовать трехпозиционный флажок в ДеревеЗначений на управляемой форме 1С предприятия 8.2 , который работает по следующему алгоритму:
* Если у элемента ДереваЗначений нет подчиненных элементов, то флажок может быть либо “включен”, либо “выключен”.
* Если у элемента есть подчиненные, то флажок “включен”, если ВКЛЮЧЕНЫ флажки у ВСЕХ подчиненных элементов, “выключен” если ВЫКЛЮЧЕНЫ флажки у ВСЕХ подчиненных элементов.
Если у некоторых подчиненных элементов флажки включены, а у некоторых выключены, то флажок родительского элемента имеет значение “неопределенно”.
* При включении флажка у родительского элемента, включаются флажки ВСЕХ подчиненных, при выключении флажка у родительского элемента, выключаются флажки ВСЕХ подчиненных.
Возьмем из первой статьи процедуру построения дерева значений и доработаем ее, добавив в дерево еще одну колонку, которая будет содержать элемент управления флажок и реализуем для него обработчик события “ПриИзменении”. Весь алгоритм сводится к обработке изменения флажка: у всех подчиненных элементов необходимо включить/выключить флажки в зависимости от состояния флажка текущего элемента, а у всех родителей текущего элемента (которые расположены на верхних уровнях иерархии) проставить флажки в состояния “включен”/”выключен”/”неопределенно” в соответствии с вышеописанным алгоритмом. Пример -
Скачивать файлы может только зарегистрированный пользователь!
Код 1C v 8.2 УП &НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Создание и заполнение "обычного" объекта прикладного типа ДеревоЗначений,
// который будет отображен на управляемой форме
ДеревоОбъект = Новый ДеревоЗначений;
ДеревоОбъект.Колонки.Добавить("Узел", Новый ОписаниеТипов("Строка"));
ДеревоОбъект.Колонки.Добавить("Пометка", Новый ОписаниеТипов("Число"));
Для к1 = 1 По 3 Цикл
СтрокаУ1 = ДеревоОбъект.Строки.Добавить();
СтрокаУ1.Узел = "Узел"+к1;
Для к2 = 1 По 3 Цикл
СтрокаУ2 = СтрокаУ1.Строки.Добавить();
СтрокаУ2.Узел = СтрокаУ1.Узел+к2;
Для к3 = 1 По 3 Цикл
СтрокаУ3 = СтрокаУ2.Строки.Добавить();
СтрокаУ3.Узел = СтрокаУ2.Узел+к3;
КонецЦикла;
КонецЦикла;
КонецЦикла;
// Создание Реквизита формы типа ДанныеФормыДерево
МассивДобавляемыхРеквизитов = Новый Массив;
МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы("Дерево",
Новый ОписаниеТипов("ДеревоЗначений")));
Для Каждого Колонка Из ДеревоОбъект.Колонки Цикл
МассивДобавляемыхРеквизитов.Добавить(Новый РеквизитФормы(Колонка.Имя,
Колонка.ТипЗначения, "Дерево"));
КонецЦикла;
ИзменитьРеквизиты(МассивДобавляемыхРеквизитов);
// Преобразование объекта прикладного типа ДеревоЗначений
// в реквизит управляемой формы (данные формы)
ЗначениеВРеквизитФормы(ДеревоОбъект, "Дерево");
// Создание элемента формы типа ТаблицаФормы для отображения дерева
ЭлементДерево = Элементы.Добавить("Дерево", Тип("ТаблицаФормы"));
ЭлементДерево.ПутьКДанным = "Дерево";
ЭлементДерево.Отображение = ОтображениеТаблицы.Дерево;
Для Каждого Колонка Из ДеревоОбъект.Колонки Цикл
НовыйЭлемент = Элементы.Добавить(Колонка.Имя, Тип("ПолеФормы"),
ЭлементДерево);
НовыйЭлемент.ПутьКДанным = "Дерево." + Колонка.Имя;
Если НЕ Колонка.Имя = "Пометка" Тогда
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
Иначе
НовыйЭлемент.Вид = ВидПоляФормы.ПолеФлажка;
НовыйЭлемент.ТриСостояния = Истина;
НовыйЭлемент.УстановитьДействие("ПриИзменении",
"ФлажокПриИзменении");
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура ФлажокПриИзменении(Элемент)
ИДТекущейСтроки = Элементы["Дерево"].ТекущаяСтрока;
Если ИДТекущейСтроки <> Неопределено Тогда
ЭлементКоллекции = ЭтаФорма["Дерево"].НайтиПоИдентификатору(
ИДТекущейСтроки);
Если ЭлементКоллекции.Пометка = 2 Тогда
ЭлементКоллекции.Пометка = 0;
КонецЕсли;
УстановкаФлажков(ЭлементКоллекции, ЭлементКоллекции.Пометка);
Родитель = ЭлементКоллекции.ПолучитьРодителя();
Пока Родитель <> Неопределено Цикл
Родитель.Пометка = ?(УстановленноДляВсех(ЭлементКоллекции),
ЭлементКоллекции.Пометка, 2);
ЭлементКоллекции = Родитель;
Родитель = ЭлементКоллекции.ПолучитьРодителя();
КонецЦикла;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура УстановкаФлажков(ЭлементКоллекции, ЗначениеПометки)
ПодчинЭлементы = ЭлементКоллекции.ПолучитьЭлементы();
Для Каждого ТекЭлемент Из ПодчинЭлементы Цикл
ТекЭлемент.Пометка = ЗначениеПометки;
УстановкаФлажков(ТекЭлемент, ТекЭлемент.Пометка);
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Функция УстановленноДляВсех(ЭлементКоллекции)
СоседниеЭлементы =
ЭлементКоллекции.ПолучитьРодителя().ПолучитьЭлементы();
Для Каждого ТекЭлемент Из СоседниеЭлементы Цикл
Если ТекЭлемент.Пометка <> ЭлементКоллекции.Пометка Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Возврат Истина;
КонецФункции
8.х
На форме имеется табличное поле, источником данных для которого является дерево значений. В одной из колонок расположен элемент управления «Флажок». Необходимо что бы он мог принимать три состояния «Включен», «Выключен» и «Неопределено». При этом состояние «Неопределено» или так называемый «серый флажок», т.е. выбранный частично, устанавливается в том случае, если не у всех подчиненных строк состояние флажка одинаковое. Так же если строка имеет подчиненные строки, то при изменении её флажка, соответствующим образом должны изменяться флажки и всех подчиненных строк.
Во-первых, добавим нашу колонку с флажком в дерево значений:
Код 1C v 8.х Дерево.Колонки.Добавить("Пометка",Новый ОписаниеТипов("Число"));
ЭлементыФормы.Дерево.СоздатьКолонки();
КолонкиДерева=ЭлементыФормы.Дерево.Колонки;
КолонкиДерева.Пометка.ДанныеФлажка="Пометка";
КолонкиДерева.Пометка.УстановитьЭлементУправления(Тип("Флажок"));
КолонкиДерева.Пометка.РежимРедактирования=РежимРедактированияКолонки.Непосредственно;
КолонкиДерева.Пометка.ТриСостоянияФлажка=Истина;
Во-вторых, при изменении флажка нужно устанавливать соответствующие значения в подчиненных строках и контролировать значение флажка в «строке-родителе»:
Код 1C v 8.х Процедура ДеревоПриИзмененииФлажка(Элемент, Колонка)
ТекущаяСтрока=Элемент.ТекущаяСтрока;
Если ТекущаяСтрока.Пометка=2 Тогда
ТекущаяСтрока.Пометка=0;
КонецЕсли;
УстановкаФлажков(ТекущаяСтрока,ТекущаяСтрока.Пометка);
Пока ТекущаяСтрока.Родитель<>Неопределено Цикл
ТекущаяСтрока.Родитель.Пометка=?(УстановленноДляВсех(ТекущаяСтрока),ТекущаяСтрока.Пометка,2);
ТекущаяСтрока=ТекущаяСтрока.Родитель;
КонецЦикла;
КонецПроцедуры
Здесь процедура УстановкаФлажков() рекурсивно устанавливает флажки в подчиненных строках:
Код 1C v 8.х Процедура УстановкаФлажков(ТекущаяСтрока,Значение)
Для Каждого Стр Из ТекущаяСтрока.Строки Цикл
Стр.Пометка=Значение;
УстановкаФлажков(Стр,Стр.Пометка);
КонецЦикла;
КонецПроцедуры
А функция УстановленноДляВсех() проверяет установлено ли одинаковое значение для всех строк на текущем уровне:
Код 1C v 8.х Функция УстановленноДляВсех(Строка)
Для Каждого Стр Из Строка.Родитель.Строки Цикл
Если Стр.Пометка<>Строка.Пометка Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Возврат Истина;
КонецФункции
Категория:
Работа с Формой (Диалог) и её элементами Экспорт и Импорт данных 1С - Microsoft Excel Экспорт
Процедура ОсновныеДействияФормыЭкспорт(Кнопка) - выгружает из указанного справочника данные в режиме экспорта в файл в формате Microsoft Excel с указанным именем, используя преобразование данных к типу число и типу строка;
Код 1C v 8.х Процедура ОсновныеДействияФормыЭкспорт(Кнопка)
Попытка
Попытка
// Загрузка объекта Microsoft Excel
Состояние("Выгрузка данных из 1С в Microsoft Excel...");
ExcelПриложение = Новый COMОбъект("Excel.Application");
Исключение
Сообщить("Ошибка при запуске Microsoft Excel."
+ Символы.ПС + ОписаниеОшибки(), СтатусСообщения.Внимание);
Возврат;
КонецПопытки;
// Создадим книгу, по умолчанию в ней уже есть листы
Книга = ExcelПриложение.WorkBooks.Add();
// Используем первый лист книги Excel
Лист = Книга.WorkSheets(1);
// Сформировать шапку документа в первой строке листа
Колонка = 1;
Для каждого стр из ТП цикл
Если стр.Выгружать Тогда
Лист.Cells(1, Колонка).Value = стр.НазваниеРеквизита;
Колонка = Колонка + 1;
КонецЕсли;
КонецЦикла;
// Выгрузить данные справочника
выборка = Справочники[ИмяСправочника].Выбрать();
СтрокаЛиста = 2;
Пока выборка.Следующий() Цикл
Колонка = 1;
Для каждого стр из ТП цикл
Если стр.Выгружать Тогда
Попытка
// Установить значение в строке и колонке
Если ТипЗнч(выборка[стр.НазваниеРеквизита])=Тип("Число") Тогда
// Установить формат для типа Число
Лист.Cells(СтрокаЛиста, Колонка).NumberFormat = "0,00";
Лист.Cells(СтрокаЛиста, Колонка).Value =
Формат(выборка[стр.НазваниеРеквизита],"ЧГ=0");
иначе
// Для всех других типов установим формат "Текстовый"
Лист.Cells(СтрокаЛиста, Колонка).NumberFormat = "@";
Лист.Cells(СтрокаЛиста, Колонка).Value =
Строка(выборка[стр.НазваниеРеквизита]);
КонецЕсли;
исключение
// в случае ошибки вывести номер строки и колонки
Сообщить("Ошибка установки значения для: " +
выборка[стр.НазваниеРеквизита]);
Сообщить("Стр: " +СтрокаЛиста+ " Кол: " +
Колонка+ " Рек: " + стр.НазваниеРеквизита);
КонецПопытки;
Колонка = Колонка + 1;
КонецЕсли;
КонецЦикла;
СтрокаЛиста = СтрокаЛиста + 1;
Состояние("Экспорт из 1С в Excel " + СтрокаЛиста);
КонецЦикла;
// Сохраним созданную книгу в файл xls
Книга.SaveAs(имяФайла);
// Обязательно закроем соединение с COM объектом для освобождения памяти
ExcelПриложение.Quit();
Сообщить("Файл выгружен успешно: " + имяФайла );
Исключение
// Обработка ошибок экспорта данных из 1С в Excel
Сообщить("Ошибка записи данных файла :" + имяФайла);
Сообщить(ОписаниеОшибки());
Попытка
ExcelПриложение.Quit();
Исключение
КонецПопытки;
КонецПопытки;
КонецПроцедуры
Импорт
Исходный код процедуры 1С для загрузки XLS файла:
Код 1C v 8.х Процедура ЧтениеXLSФайла(Элемент)
Если ПустаяСтрока(ИмяФайла) Тогда
Предупреждение("Для запуска обработки необходимо предварительно выбрать файл Microsoft Excel.");
Возврат;
КонецЕсли;
Попытка
// Загрузка Microsoft Excel
Состояние("Загрузка Microsoft Excel...");
ExcelПриложение = Новый COMОбъект("Excel.Application");
Исключение
Сообщить("Ошибка при загрузке Microsoft Excel." + Символы.ПС + ОписаниеОшибки(), СтатусСообщения.Внимание);
Возврат;
КонецПопытки;
Попытка
// Открытие файла Microsoft Excel
Состояние("Открытие файла Microsoft Excel...");
ExcelФайл = ExcelПриложение.WorkBooks.Open(ИмяФайла);
Исключение
Сообщить("Ошибка открытия файла Microsoft Excel." + ИмяФайла + Символы.ПС + ОписаниеОшибки(), СтатусСообщения.Внимание);
КонецПопытки;
Попытка
// Обработка файла Microsoft Excel
Состояние("Обработка файла Microsoft Excel...");
// Читаем данные первого листа книги
ExcelЛист = ExcelФайл.Sheets(1);
// Определить количество строк и колонок выбранного листа книги Excel
xlCellTypeLastCell = 11;
ExcelПоследняяСтрока = ExcelЛист.Cells.SpecialCells(xlCellTypeLastCell).Row;
ExcelПоследняяКолонка = ExcelЛист.Cells.SpecialCells(xlCellTypeLastCell).Column;
Исключение
Сообщить("Ошибка открытия листа №1 Microsoft Excel." + Символы.ПС + ОписаниеОшибки(), СтатусСообщения.Внимание);
// Закрыть COM соединение для экономии памяти
ExcelПриложение.Quit();
КонецПопытки;
// Создание описателя типов для таблицы значений
КЧ = Новый КвалификаторыЧисла(15,2);
КС = Новый КвалификаторыСтроки(50);
Массив = Новый Массив;
Массив.Добавить(Тип("Строка"));
ОписаниеТиповС = Новый ОписаниеТипов(Массив, , КС);
Массив.Очистить();
Массив.Добавить(Тип("Число"));
ОписаниеТиповЧ = Новый ОписаниеТипов(Массив, , ,КЧ);
// Очистить предыдущие значения
ТаблицаДокумента.Очистить();
ТаблицаДокумента.Колонки.Очистить();
// Создать колонки табличного документа
ТаблицаДокумента.Колонки.Добавить("Номер",ОписаниеТиповС,"Номер",5);
ТаблицаДокумента.Колонки.Добавить("Артикул",ОписаниеТиповС,"Артикул",11);
ТаблицаДокумента.Колонки.Добавить("Описание",ОписаниеТиповС,"Описание",25);
ТаблицаДокумента.Колонки.Добавить("Цена",ОписаниеТиповЧ,"Цена",6);
// Последовательное чтение строк с выбранного листа
Для Строка = 1 По ExcelПоследняяСтрока Цикл
// Обработка нажатия Ctrl + Break
ОбработкаПрерыванияПользователя();
// Добавить данные в табличную часть экранной формы
Стр=ТаблицаДокумента.Добавить();
Стр.Номер = Строка;
Попытка
Стр.Артикул = ExcelЛист.Cells(Строка, 1).Value;
Стр.Описание = ExcelЛист.Cells(Строка, 2).Value;
Стр.Цена = ExcelЛист.Cells(Строка, 3).Value;
Исключение
// Не редко происходит ошибка конвертации отдельной ячейки документа
Сообщить("Ошибка чтения строки файла Microsoft Excel." + Строка + Символы.ПС + ОписаниеОшибки(), СтатусСообщения.Внимание);
КонецПопытки;
// Отобразить информацию о ходе выполнения обработки
Состояние("Обработка файла Microsoft Excel : "
+ "строка " + Строка + " из " + ExcelПоследняяСтрока);
КонецЦикла;
// Закрыть COM соединение для экономии памяти
ExcelПриложение.Quit();
// Отобразить результаты загрузки в форме элемента
ЭлементыФормы.ТаблицаДокумента.Значение = ТаблицаДокумента;
ЭлементыФормы.ТаблицаДокумента.СоздатьКолонки();
КонецПроцедуры // ЧтениеXLSФайла(Элемент)
Категория:
Работа с Microsoft Office и OpenOffice Как выгрузить результат запроса с отбором по регистратору в табличную часть, табличное поле? Выгрузка результата запроса в табличную часть документа, справочника
Код 1C v 8.х Запрос=Новый Запрос;
// Получим суммы начисленные документами НачислениеЗарплатыРаботникамОрганизаций в ПериодВзаиморасчетов
Запрос.Текст="
|ВЫБРАТЬ
| ВзаиморасчетыСРаботникамиОрганизаций.Период,
| ВзаиморасчетыСРаботникамиОрганизаций.Регистратор,
| ВзаиморасчетыСРаботникамиОрганизаций.Физлицо,
| ВзаиморасчетыСРаботникамиОрганизаций.Организация,
| ВзаиморасчетыСРаботникамиОрганизаций.ПериодВзаиморасчетов,
| ВзаиморасчетыСРаботникамиОрганизаций.СуммаВзаиморасчетов
|ИЗ
| РегистрНакопления.ВзаиморасчетыСРаботникамиОрганизаций КАК ВзаиморасчетыСРаботникамиОрганизаций
|ГДЕ
| ВзаиморасчетыСРаботникамиОрганизаций.ПериодВзаиморасчетов = &ПериодВзаиморасчетов
| И ВзаиморасчетыСРаботникамиОрганизаций.Регистратор ССЫЛКА Документ.НачислениеЗарплатыРаботникамОрганизаций
|";
Запрос.УстановитьПараметр("ПериодВзаиморасчетов",Дата("01.09.2009 0:00:00"));
Результат = Запрос.Выполнить();
// Выгрузим Результат Запроса в ТЗ
ТзВрем = Результат.Выгрузить();
Для Каждого стр Из Тзврем Цикл
// ТаблЧастьДокРезультат - Табличная часть на форме, создаем в ней новую строку
НовСтр=ТаблЧастьДокРезультат.Добавить();
// Заполняем значения новой строки значениями результат запроса:
ЗаполнитьЗначенияСвойств(новстр, стр);
//ВНИМАНИЕ!!! ЗаполнитьЗначенияСвойств( - работает только когда имена колонок табл части и результата запроса совпадают!
//Если не совпадают, то обычным способом:
НовСтр.Дата = стр.ПериодВзаиморасчетов;
НовСтр.Сумма = стр.СуммаВзаиморасчетов;
КонецЦикла;
Выгрузка результата запроса в табличное поле с типом данных Таблица Значений
Код 1C v 8.х Запрос=Новый Запрос;
// Получим суммы начисленные документами НачислениеЗарплатыРаботникамОрганизаций в ПериодВзаиморасчетов
Запрос.Текст="
|ВЫБРАТЬ
| ВзаиморасчетыСРаботникамиОрганизаций.Период,
| ВзаиморасчетыСРаботникамиОрганизаций.Регистратор,
| ВзаиморасчетыСРаботникамиОрганизаций.Физлицо,
| ВзаиморасчетыСРаботникамиОрганизаций.Организация,
| ВзаиморасчетыСРаботникамиОрганизаций.ПериодВзаиморасчетов,
| ВзаиморасчетыСРаботникамиОрганизаций.СуммаВзаиморасчетов
|ИЗ
| РегистрНакопления.ВзаиморасчетыСРаботникамиОрганизаций КАК ВзаиморасчетыСРаботникамиОрганизаций
|ГДЕ
| ВзаиморасчетыСРаботникамиОрганизаций.ПериодВзаиморасчетов = &ПериодВзаиморасчетов
| И ВзаиморасчетыСРаботникамиОрганизаций.Регистратор ССЫЛКА Документ.НачислениеЗарплатыРаботникамОрганизаций
|";
Запрос.УстановитьПараметр("ПериодВзаиморасчетов",Дата("01.09.2009 0:00:00"));
Результат = Запрос.Выполнить();
// Выгрузим Результат Запроса в ТЗ
ТзВрем = Результат.Выгрузить();
// ТЗРезультат - это Табличное Поле на Форме, присваиваем ему таблицу значений
ТЗРезультат=ТзВрем;
//Создаем колонки в табличном поле, после чего видим в поле тз
ЭлементыФормы.ТЗРезультат.СоздатьКолонки();
Категория:
Запросы Функция ЗНАЧЕНИЕ Функция ЗНАЧЕНИЕ - Позволяет использовать прямо в текстах запроса предопределенные в конфигураторе данные. (т.е. позволяет избавиться от необходимости передавать их параметрами к запросу).
Использование предопределенных данных конфигурации
Например:
можно было бы написать в запросе:
Код 1C v 8.х | ВзаиморасчетыСПокупателямиОстатки.Проект = &ПроектыПустаяСсылка
а потом передать в запрос параметр:
Код 1C v 8.х Запрос.УстановитьПараметр("ПроектыПустаяСсылка", Справочник.Проекты.ПустаяСсылка());
А при помощи
ЗНАЧЕНИЕ будет так:
Код 1C v 8.х | ВзаиморасчетыСПокупателямиОстатки.Проект = ЗНАЧЕНИЕ(Справочник.Проекты.ПустаяСсылка)
Примеры использования:
Код 1C v 8.х //ПРИМЕР 1 (Получение паспортный данных сотрудника)
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Физлицо", Физлицо);
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ПаспортныеДанныеФизЛицСрезПоследних.ДокументВид,
| ПаспортныеДанныеФизЛицСрезПоследних.ДокументСерия,
| ПаспортныеДанныеФизЛицСрезПоследних.ДокументНомер,
| ПаспортныеДанныеФизЛицСрезПоследних.ДокументДатаВыдачи,
| ПаспортныеДанныеФизЛицСрезПоследних.ДокументКемВыдан,
| ПаспортныеДанныеФизЛицСрезПоследних.ДокументКодПодразделения,
| "","" + АдресаФактические.Поле1 + "","" + АдресаФактические.Поле2 + "","" + АдресаФактические.Поле3 + "","" + АдресаФактические.Поле4 + "","" + АдресаФактические.Поле5 + "","" + АдресаФактические.Поле6 + "","" + АдресаФактические.Поле7 + "","" + АдресаФактические.Поле8 + "","" + АдресаФактические.Поле9 КАК АдресФактический,
| "","" + АдресПрописки.Поле1 + "","" + АдресПрописки.Поле2 + "","" + АдресПрописки.Поле3 + "","" + АдресПрописки.Поле4 + "","" + АдресПрописки.Поле5 + "","" + АдресПрописки.Поле6 + "","" + АдресПрописки.Поле7 + "","" + АдресПрописки.Поле8 + "","" + АдресПрописки.Поле9 КАК АдресПоПрописке,
| ДомашниеТелефоны.Поле3 КАК ТелефонДомашний
|ИЗ
| Справочник.ФизическиеЛица КАК ФизическиеЛица
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПаспортныеДанныеФизЛиц.СрезПоследних(, ФизЛицо = &ФизЛицо) КАК ПаспортныеДанныеФизЛицСрезПоследних
| ПО ФизическиеЛица.Ссылка = ПаспортныеДанныеФизЛицСрезПоследних.ФизЛицо
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КонтактнаяИнформация КАК ДомашниеТелефоны
| ПО ФизическиеЛица.Ссылка = ДомашниеТелефоны.Объект
| И (ДомашниеТелефоны.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ТелефонФизЛица))
| И (ДомашниеТелефоны.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.Телефон))
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КонтактнаяИнформация КАК АдресаФактические
| ПО ФизическиеЛица.Ссылка = АдресаФактические.Объект
| И (АдресаФактические.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ФактАдресФизЛица))
| И (АдресаФактические.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.Адрес))
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КонтактнаяИнформация КАК АдресПрописки
| ПО (ФизическиеЛица.Ссылка = АдресаФактические.Объект)
| И (АдресаФактические.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ЮрАдресФизЛица))
| И (АдресаФактические.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.Адрес))
|ГДЕ
| ФизическиеЛица.Ссылка = &Физлицо";
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
АдресПроживания = Выборка.АдресФактический;
УдостоверениеЛичности = Строка(Выборка.ДокументВид)+"; "+Выборка.ДокументСерия+"; "+Выборка.ДокументНомер+"; "+Формат(Выборка.ДокументДатаВыдачи,"ДЛФ=D");
Телефон = Выборка.ТелефонДомашний;
КонецЕсли;
//ПРИМЕР 2
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ВидыНоменклатуры.Ссылка как ссылка,
| ВидыНоменклатуры.Порядок
|ИЗ
| Перечисление.ВидыНоменклатуры КАК ВидыНоменклатуры
|ГДЕ
| ВидыНоменклатуры.Ссылка = Значение(Перечисление.ВидыНоменклатуры.Услуга) ";
ТЗ = Новый ТаблицаЗначений;
ТЗ = запрос.Выполнить().Выгрузить();
ЭлементыФормы.ТабличноеПоле1.Значение = ТЗ;
ЭлементыФормы.ТабличноеПоле1.СоздатьКолонки();
Категория:
Запросы Использование Предопределенных данных конфигурации Текст запроса может содержать предопределенные данные конфигурации, такие как:
- значения перечислений;
- предопределенные данные:
- справочников;
- планов видов характеристик;
- планов счетов;
- планов видов расчетов;
- пустые ссылки;
- значения точек маршрута бизнес-процессов.
Также текст запроса может содержать значения системных перечислений, которые могут быть присвоены полям в таблицах базы данных:
ВидДвиженияНакопления, ВидСчета и
ВидДвиженияБухгалтерии .
Обращение в запросах к предопределенным данным конфигурации и значениям системных перечислений осуществляется с помощью литерала функционального типа:
ЗНАЧЕНИЕ(<ПредставлениеЗначения>)
Для системных перечислений
<ПредставлениеЗначения> имеет вид:
<ИмяСистемногоПеречистления>.<Значение>
Допустимые имена системных перечислений приведены выше, с перечнем допустимых для каждого из них значений можно ознакомиться в его описании.
Для предопределенных данных конфигурации
<ПредставлениеЗначения> имеет вид:
<ТипПредопределенногоЗначения>.<ИмяОбъектаМетаданных>.<Значение>
<ТипПредопределенногоЗначения> может быть:
- Справочник (Catalog);
- ПланВидовХарактеристик (ChartOfCharacteristicTypes);
- ПланСчетов (ChartOfAccounts);
- ПланВидовРасчета (ChartOfCalculationTypes);
- Перечисление (Enum).
В качестве
<ИмяОбъектаМетаданных> указывается имя объекта метаданных, как оно задано в конфигураторе.
Для определенных в конфигурации перечислений <Значение> указывается как имя соответствующего объекта метаданных типа ЗначаниеПеречисления. Для всех остальных типов предопределенных значений <Значение> указывается как имя предопределенного элемента данных, как оно указано в конфигураторе, или
ПустаяСсылка (EmptyRef) для указания пустой ссылки.
Для точек маршрутов бизнес-процессов
<ПредставлениеЗначения> имеет вид:
БизнесПроцесс.<ИмяОбъектаМетаданных>.Точка.<ИмяТочкиМаршрута>.
Ниже приведены несколько фрагментов запросов, поясняющих использование предопределенных данных в запросах:
Код 1C v 8.х ГДЕ Город = ЗНАЧЕНИЕ(Справочник.Города.Москва)
ГДЕ Город = ЗНАЧЕНИЕ(Справочник.Города.ПустаяСсылка)
ГДЕ ТипТовара = ЗНАЧЕНИЕ(Перечисление.ВидыТоваров.Услуга)
ГДЕ ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)
ГДЕ ТочкаМаршрута = ЗНАЧЕНИЕ(БизнесПроцесс.БизнесПроцесс1.Точка.Действие1)
еще пример:
Код 1C v 8.х Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ВидыНоменклатуры.Ссылка как ссылка,
| ВидыНоменклатуры.Порядок
|ИЗ
| Перечисление.ВидыНоменклатуры КАК ВидыНоменклатуры
|ГДЕ
| ВидыНоменклатуры.Ссылка = Значение(Перечисление.ВидыНоменклатуры.Услуга) ";
ТЗ = Новый ТаблицаЗначений;
ТЗ = запрос.Выполнить().Выгрузить();
ЭлементыФормы.ТабличноеПоле1.Значение = ТЗ;
ЭлементыФормы.ТабличноеПоле1.СоздатьКолонки();
Категория:
Запросы