8.х 1С и Excel

Тема в разделе "Конфигурирование на платформе "1С:Предприятие 8"", создана пользователем konst, 1 май 2009.

  1. uza
    Offline

    uza 1С, VBA (EXCEL), VB (.NET + WEB)

    Регистрация:
    10 июл 2007
    Сообщения:
    1.845
    Симпатии:
    1
    Баллы:
    29
    Попробуйте вот что:
    1) Устанавливаетй значение не Cells у, а Range(Адрес)
    2) Не Formula, а FormulaR1C1 (в этом случае используется не абсолютный адрес ячейки, а относительный.
    Range("C1").FormulaR1C1 = "=R[1]C[-2]+RC[-1]" - означает, ячека С1 будет хранить формулу A2+B1
    Range("B3").FormulaR1C1 = "=RC[-1]+3" - означает B3 = A3+3
    Range("C3").FormulaR1C1 = "=RC[-2]+RC[-1]*Перем1" - есть A3+B3 * Перем1 (именнованная ячейка).

    Относительный адрес оно даже и лучше. Не надо каждый раз собирать строку формулы, один раз собрали и во все строки одну формулу и ставите (если данные берутся из поименованных ячеек и из колонок этой же строки - смещения то все будут одинковыми)
    Вот как то так.
    Оно конечно можно и Formula работать, только чур, что открытый ексель должен иметь Стиль ссылок R1C1 (иначе писать формулу надо не через R/C а через A1*B12*$B$14).
    А EXCEL считает потом верно потому, что на самом деле, он формулы, преобразоывывает и впихивает в FormulaR1C1, а не в formula (попробуйте написать макрос, он это покажет... нечаянно :) )
  2. TopicStarter Overlay
    konst
    Offline

    konst Опытный в 1С

    Регистрация:
    17 мар 2009
    Сообщения:
    71
    Симпатии:
    0
    Баллы:
    26
    Спасибо uza,

    У меня есть эксель в котором с ячейку вводится число, но там что-то прописано и при вводе числа больше чем заданное, выводится ошибка типа "введите цифру от 1 до 5" подскажите плиз как это исправить и где можно у видеть что там прописано. Вроде бы макросов нет никаких, не могу понять в чем дело.
  3. uza
    Offline

    uza 1С, VBA (EXCEL), VB (.NET + WEB)

    Регистрация:
    10 июл 2007
    Сообщения:
    1.845
    Симпатии:
    1
    Баллы:
    29
    Это ограничение ексель.
    Где его смотреть - зависит от версии MS Office
    В 2003 это делается так:
    Встаем в ячейку (или выделяем весь столбец)
    Данные\Проверка - и смотрим что там за ограничение.
    Скорее всего там ограничение, что тип вводимых данных = Число
    Минимум = 1
    Максимум = 5
    И в полях предупреждений и ошибок указанная вами надпись.

    В 2007м тоже самое, толко до этого пункта меню не помню как добираться (немного хитрее чем в 2003... просто нет под рукой 2007 - ну не легло на сердце это гамно)
  4. TopicStarter Overlay
    konst
    Offline

    konst Опытный в 1С

    Регистрация:
    17 мар 2009
    Сообщения:
    71
    Симпатии:
    0
    Баллы:
    26
    Можно ли прописать эту проверку в 1С через Лист.Cells(1,1)
  5. uza
    Offline

    uza 1С, VBA (EXCEL), VB (.NET + WEB)

    Регистрация:
    10 июл 2007
    Сообщения:
    1.845
    Симпатии:
    1
    Баллы:
    29
    Повторю вам свое возвание "разберитесь с записью макросов в EXCEL" - дело пары часов от силы :)
    Сервис/Макрос/Начать запись
    И начинаете ворочать мышкой да клавой данные. Форматировать, сохранять, удалять и добавлять.
    А EXCEL (тоже самое и в WORD и в многих других проложениях пакета MS OFFICE) записывает вам программный код, повторяющий ваши действия.
    Затем остановите запись макроса, нажмите Alt+F11 и перейдите в редактор VBA - где вы и увидете, что надо написать
    (собственно текст уже написанной процедуры - макроса тобишь), чтобы повторить действия, но программными средствами.
    Что касается назначения ограничений на ячейку (Вводимое значение = Число, Минимальное = 1, Максимальное = 10, при вводе
    неверного значения блокировать ввод с выводом сообщения)
    то код такой:
    Код:
    Range("A3").Select
    With Selection.Validation
    .Delete
    .Add Type:=xlValidateWholeNumber, AlertStyle:=xlValidAlertStop, _
    Operator:=xlBetween, Formula1:="1", Formula2:="10"
    .IgnoreBlank = True
    .InCellDropdown = True
    .InputTitle = ""
    .ErrorTitle = "Ошибка ввода значения"
    .InputMessage = "Введите целое число от 1 до 10"
    .ErrorMessage = "Введите целое число от 1 до 10"
    .ShowInput = True
    .ShowError = True
    End With
    
    
    
    Для группы ячеек (допустим для всей колонки. Строку Range("A3").Select следует заменить на Range("A:A").Select

    Для 1С это можно оформить так:
    Код:
    //инициализируем константы EXCEL, 
    //можно конечно подставлять и готовые значения потом.
    //но если мы активно используем работу с EXCEL, 
    //то проще один раз написать, пусть и большой, 
    //блок инициализации разнообразных констат, и потом "копипаситить" макросы
    xlValidateWholeNumber = 1;
    xlValidAlertStop = 1;
    xlBetween = 1;
    
    ДиапазонЯчеек = ЛистЕКСЕЛЬ.Range("A:A");
    ДиапазонЯчеект.Validation.Delete; //удаляем старые проверки
    ДиапазонЯчеект.Validation.Add(xlValidateWholeNumber, xlValidAlertStop, xlBetween, "1", "10");
    //добавляем новое ограничение "от 1 до 10"
    ДиапазонЯчеект.Validation..IgnoreBlank = True
    ДиапазонЯчеект.Validation..InCellDropdown = True
    ДиапазонЯчеект.Validation..InputTitle = ""
    ДиапазонЯчеект.Validation.ErrorTitle = "Ошибка ввода значения"
    ДиапазонЯчеект.Validation.InputMessage = "Введите целое число от 1 до 10"
    ДиапазонЯчеект.Validation.ErrorMessage = "Введите целое число от 1 до 10"
    ДиапазонЯчеект.Validation.ShowInput = True
    ДиапазонЯчеект.Validation.ShowError = True
    
    
    
  6. TopicStarter Overlay
    konst
    Offline

    konst Опытный в 1С

    Регистрация:
    17 мар 2009
    Сообщения:
    71
    Симпатии:
    0
    Баллы:
    26
    Определяю кол-во строк и столбцов в экселе, с которого буду грузить данные, вот так
    xlCellTypeLastCell = 11;
    ExcelПоследняяСтрока = ExcelЛист.Cells.SpecialCells(xlCellTypeLastCell).Row;
    ExcelПоследняяКолонка = ExcelЛист.Cells.SpecialCells(xlCellTypeLastCell).Column;

    первую группировку и все ее внутренние группировки в экселе читает нормально(разворачивает все внутренние группировки), а вот группировку идущую после первой не разворачивает, т.е. строки которые есть в этой группировке не определяет, подскажите плиз что я не так делаю
  7. uza
    Offline

    uza 1С, VBA (EXCEL), VB (.NET + WEB)

    Регистрация:
    10 июл 2007
    Сообщения:
    1.845
    Симпатии:
    1
    Баллы:
    29
    Если я правильно понял (а из вашего вопроса трудно что либо понять ;) )
    То вы наталкиваетесь на проблему, что вторая группировка (сгруппированная ячейка) - она же и последняя, не определяются через спешиалкеллс.
    Так вот, уведомляю вас, что ExcelЛист.Cells.SpecialCells(xlCellTypeLastCell).Row - вернет последнюю строку, в которой содержится ВВЕДЕННОЕ ЗНАЧЕНИЕ.
    Т.е. вот берем и вводим в ячейку A3 значение = 1, а затем объединяем ячейки А3 и А4 (при этом значение 1 хрантиться по прежнему в А3ей ячейке)
    И конструкция ExcelЛист.Cells.SpecialCells(xlCellTypeLastCell).Row возвращате значение 3!

    В этом случае, если вы хотите действительно обойти все строки этой группировки (хотя нафига, если там нет значений?)
    Вам необходимо сделать следующее
    1) Узнаем, входит ли последняя ячейка в группировку
    2) Получаем диапазон выделенной ячейки
    Код:
    Dim Rng As Range
    Dim Adr As String
    Set Rng = Range("C9") 'захватили нашу ячейку как область, можно конечно обращаться и через
    '       МойЛистЕксель.Cells(9,3) - но так кода меньше
    If Rng.MergeCells Then
    'если это кусок объединенной ячейки, то получим адрес всей объединенной области
    Adr = Rng.MergeArea.Address()
    'можно использовать различные варианты получения адреса. Вот кусок справки
    'MsgBox mc.Address()                              [доллар]A[доллар]1
    'MsgBox mc.Address(RowAbsolute:=False)            ' [доллар]A1
    'MsgBox mc.Address(ReferenceStyle:=xlR1C1)        ' R1C1
    
    Else
    'эта ячейка, не является частью объединенки - поэтому получам только ее адрес
    Adr = Rng.Address()
    End If
    
    
    
  8. TopicStarter Overlay
    konst
    Offline

    konst Опытный в 1С

    Регистрация:
    17 мар 2009
    Сообщения:
    71
    Симпатии:
    0
    Баллы:
    26
    У меня в экселе есть группировки строк (2 группировки с внутренними группировками), 1-ая группировка, содержащая в себе другие группировки - считывается нормально, а вот последняя группировка и ее внутренние группировке не читаются, вернее читается только строка этой группировки, а вот внутренние группировки не видит, почему-то.

    Может можно узнать как-то количество внутренних группировок, чтоб потом сделать так ActiveSheet.Outline.ShowLevels RowLevels:=4. т.е если руками, то нажать на последнюю 4 ку в левом верхнем углу(для группировок) и все группировки развернуть(откроются)
  9. uza
    Offline

    uza 1С, VBA (EXCEL), VB (.NET + WEB)

    Регистрация:
    10 июл 2007
    Сообщения:
    1.845
    Симпатии:
    1
    Баллы:
    29
    Ну дык откройте ексель. Откройте в нем свою книгу.
    Начните запись макроса, нажмите нужные вам комбинации клавиш.
    Остановите запись макроса. Нажмите Alt+F11 да и посмотрите какой код сгенерировал EXCEL.
    А далее транслируйте его в 1Ску.
  10. TopicStarter Overlay
    konst
    Offline

    konst Опытный в 1С

    Регистрация:
    17 мар 2009
    Сообщения:
    71
    Симпатии:
    0
    Баллы:
    26
    Дело в том, что в экселе допустим 4 ровня группировки и макрос соответственно ActiveSheet.Outline.ShowLevels RowLevels:=4, а может быть разное количество уровне группировок т.к. эксель создается пользователем(обработочкой которую и пишу), а уровень группировок определяется в зависимости от структуры номенклатуры которая выгружается

    Вот и пытаюсь найти функцию в экселе или свойство которое бы возвращало количество уровней группировок на листе
  11. uza
    Offline

    uza 1С, VBA (EXCEL), VB (.NET + WEB)

    Регистрация:
    10 июл 2007
    Сообщения:
    1.845
    Симпатии:
    1
    Баллы:
    29
    Я уже не понимаю что вы делаете, зачем вы это делаете и соответственно правильно ли вы это делаете.
    Если EXCEL файл создается вашей обработкой, то почему вы не знаете количества уровней группировки?
    Если вы не умеете с этим работать (а также не умеете запустить редактор VBA ексель и пройтись там по объектной модели и поюзать кнопень F1), то может быть стоит делать как то по другому?
    Вот нивжисть не поверю, что вы не можете, хоть при 127 ми уровнях группировки "втупую" пройтись по строкам EXCEL.

    Для того, чтобы мне что то понять, что вам нужно, нужно хотябы показать пример того, с чем вы боретесь.
    Ну или "рыбу" листа EXCEL мне выслать (будет время - гляну). Мыло отправил в личку.
  12. TopicStarter Overlay
    konst
    Offline

    konst Опытный в 1С

    Регистрация:
    17 мар 2009
    Сообщения:
    71
    Симпатии:
    0
    Баллы:
    26
  13. uza
    Offline

    uza 1С, VBA (EXCEL), VB (.NET + WEB)

    Регистрация:
    10 июл 2007
    Сообщения:
    1.845
    Симпатии:
    1
    Баллы:
    29
    Пардон, и чего там было [заниматься ######ом]?

    Код:
    xlLastCell			= 11;
    ПорогСрабатывания	= 3;
    СчитанноПустых		= 0;
    Путь_Ексель_Книги	= "C:\Downloads\77.xls";
    ПерваяСтрокаДанных	= 7;
    
    
    //*********************************************************************************************
    //открываем файл ексель и получаем лист книги как отдельный объект
    Excel = Новый COMОбъект("Excel.Application");
    Excel.WorkBooks.Open(Путь_Ексель_Книги);
    ExcelSheet = Excel.Sheets("Прайс");
    //*********************************************************************************************
    //определяем номер последней заполненной строки
    //
    //НомерПоследнейСтроки	= ExcelSheet.Cells.SpecialCells(xlLastCell).Row;
    //вот так действительно возвращает 21, когда надо вернуть 23.
    //можно долго и упорно насиловать справку, в поисках решения.
    //А можно тупо и просто, обходом
    НомерПоследнейСтроки	= 0;
    Сч						= ПерваяСтрокаДанных;
    Пока СчитанноПустых < ПорогСрабатывания Цикл
    СтрокаНаименованияТовара	= СокрЛП(ExcelSheet.Range("A"+Сч).Text);
    Если СтрДлина(СтрокаНаименованияТовара)=0 Тогда
    СчитанноПустых	= СчитанноПустых + 1;
    Иначе
    НомерПоследнейСтроки	= Сч;
    СчитанноПустых			= 0;
    КонецЕсли; 
    Сч	= Сч + 1;
    КонецЦикла; 
    Сообщить("Номер последней строки данных в EXCEL="+НомерПоследнейСтроки);
    //*********************************************************************************************
    //ну а теперь втупую считываем данные в таблицу значений
    тзДанные	= Новый ТаблицаЗначений;
    тзДанные.Колонки.Добавить("Колонка1");
    тзДанные.Колонки.Добавить("Колонка2");
    тзДанные.Колонки.Добавить("Колонка3");
    
    Для Сч=ПерваяСтрокаДанных По НомерПоследнейСтроки Цикл
    СтрокаТЗ	= тзДанные.Добавить();
    СтрокаТЗ.Колонка1	= ExcelSheet.Range("A"+Сч).Text;
    СтрокаТЗ.Колонка2	= ExcelSheet.Range("B"+Сч).Text;
    СтрокаТЗ.Колонка3	= ExcelSheet.Range("C"+Сч).Text;
    КонецЦикла; 
    //*********************************************************************************************
    //явим миру то, что мы считали
    тзДанные.ВыбратьСтроку();
    //*********************************************************************************************
    //закрываем EXCEL
    Excel.Quit();
    //*********************************************************************************************
    
    P.S.
    Я мыло нафига в личку писал? Знаетели, не у всех, на работе депозиты, мегашары, и прочие одноглазики открыты ;)
    Ето мне, как собственно перцу начальствующей должности дозволенно ходить "мимо" прокси....
    Больше так не делайте.
  14. TopicStarter Overlay
    konst
    Offline

    konst Опытный в 1С

    Регистрация:
    17 мар 2009
    Сообщения:
    71
    Симпатии:
    0
    Баллы:
    26
    ОГРОМНОЕ СПАСИБО...
  15. TopicStarter Overlay
    konst
    Offline

    konst Опытный в 1С

    Регистрация:
    17 мар 2009
    Сообщения:
    71
    Симпатии:
    0
    Баллы:
    26
    В экселе можно выделить ячейку, где записана формула, захватив за нижний правый угол, и потянуть... тем самым скопировав содержимое.
    Вот хотелось сделать что-то подобное из 1С, в макросе который записал, чет ничего не понял, может кто сталкивался, подскажите плиз...

    Столкнулся с такой проблемой - формирую формулу таким образом
    ФормулаНачало = "=";
    ФормулаКонец = "0";
    СтрашийИндекс = ТипЦен.ВГраница()+1;
    Для Сч = 0 По ТипЦен.ВГраница() Цикл
    Число1 = 2+Сч;
    СтрашийИндекс = СтрашийИндекс - 1;
    ФормулаНачало = ФормулаНачало + "IF(ТипЦен="+СтрашийИндекс+",RC[-"+Число1+"]*RC[-1],";
    КонецЦикла;

    Для Сч = 0 По ТипЦен.ВГраница() Цикл
    ФормулаКонец = ФормулаКонец + ")";
    КонецЦикла;

    Формула = ФормулаНачало + ФормулаКонец;

    В результате получаю примерно следующее
    "=IF(ТипЦен=7,RC[-2]*RC[-1],IF(ТипЦен=6,RC[-3]*RC[-1],IF(ТипЦен=5,RC[-4]*RC[-1],IF(ТипЦен=4,RC[-5]*RC[-1],IF(ТипЦен=3,RC[-6]*RC[-1],IF(ТипЦен=2,RC[-7]*RC[-1],IF(ТипЦен=1,RC[-8]*RC[-1],IF(ТипЦен=0,RC[-9]*RC[-1],0))))))))
    для 8 типов цен

    и

    =IF(ТипЦен=8,RC[-2]*RC[-1],IF(ТипЦен=7,RC[-3]*RC[-1],IF(ТипЦен=6,RC[-4]*RC[-1],IF(ТипЦен=5,RC[-5]*RC[-1],IF(ТипЦен=4,RC[-6]*RC[-1],IF(ТипЦен=3,RC[-7]*RC[-1],IF(ТипЦен=2,RC[-8]*RC[-1],IF(ТипЦен=1,RC[-9]*RC[-1],IF(ТипЦен=0,RC[-10]*RC[-1],0)))))))))
    для 9 типов цен

    Проблема в том, что формула для 8 типов цен выводиться в эксель нормально, а вот для 9 при выводе пишет ошибку

    даже не знаю в чем и проблема, вроде бы все правильно, но почему не работает, подскажите плиз...
  16. uza
    Offline

    uza 1С, VBA (EXCEL), VB (.NET + WEB)

    Регистрация:
    10 июл 2007
    Сообщения:
    1.845
    Симпатии:
    1
    Баллы:
    29
    1) Неплохо бы форматировать сообщение так, чтобы оно влазило в "стандартный" экран (1024 х 768)
    2) Неплохо бы код помещать в тег CODE
    3) Неплохо бы текст исходный форматировать, для удобства чтения.
    4) Попробуйте писать не такую длинную формулу, а разбить ее на несколько подформул, записываемых в отдельные ячейки.
    Колонки, промежуточных расчетов можно скрыть.
    Разбирать такую длинющую формулу глазами... ну конечно не стометровый XML руками парсить - но все же.
    Ну или хотя бы оформите вашу формулу в разбивке на несколько строк (отформатируйте строку).

    А если мы возьмем, и прочитаем справку ексель, которая выдается при появлении ошибки. То обноружим следующее:
  17. alekse
    Offline

    alekse

    Регистрация:
    9 окт 2007
    Сообщения:
    17
    Симпатии:
    0
    Баллы:
    1
    Как определить максимальный уровень группировки без перебора строк? Я сейчас перебираю каждую строку (делаю активными) и получаю для каждой значение уровня группировки
    Код:
    Для Row=1 По RowCount Цикл
    Уровень = Число(СоответстиеЗагрузки["EXCEL"].ActiveSheet.Rows(Row).OutlineLevel);
    КонецЦикла;
    
    
  18. JVN
    Offline

    JVN Опытный в 1С

    Регистрация:
    25 июн 2009
    Сообщения:
    95
    Симпатии:
    0
    Баллы:
    26
    подскажите пожалуйста, как можно из 1С в документ excel выгрузить табличную часть, т. е. есть заранее считанный шаблон, в котором необходимо скопировать строку из этого же шаблона с последующим заполнением

    Код:
    Макет = ПолучитьМакет("СчетЗаказXLS"); 
    Книга = Макет.Получить();
    Лист = Книга.WorkSheets(1);
    Лист.Activate();
    Лист.Cells(10,1).Value  = ПараметрыПечати.БанкПолучателяПредставление;
    Лист.Cells(10,22).Value = ПараметрыПечати.БикБанкаПолучателя;
    Лист.Cells(11,22).Value = ПараметрыПечати.СчетБанкаПолучателяПредставление;
    Лист.Cells(13,3).Value  = ПараметрыПечати.ИНН;
    Лист.Cells(13,12).Value = ПараметрыПечати.КПП;
    Лист.Cells(14,1).Value  = ПараметрыПечати.ПредставлениеПоставщикаДляПлатПоручения;
    Лист.Cells(13,22).Value = ПараметрыПечати.СчетПолучателяПредставление;
    Лист.Cells(18,1).Value  = СтрЗаменить(ПараметрыПечати.ТекстЗаголовка, "Счет на оплату", "Счет-договор");
    Лист.Cells(20,5).Value  = ПараметрыПечати.ПредставлениеПоставщика;
    Лист.Cells(22,5).Value  = ПараметрыПечати.ПредставлениеПолучателя;
    
    Лист.Range("R25","C1").Copy();
    Лист.Range("R26","C1").Activate();
    Лист.Paste();
    
    
    Лист.Cells(27,33).Value = ПараметрыПечати.Всего;
    Лист.Cells(28,33).Value = ПараметрыПечати.ВсегоНДС;
    Лист.Cells(29,1).Value  = ПараметрыПечати.ИтоговаяСтрока;
    Лист.Cells(30,1).Value  = ПараметрыПечати.СуммаПрописью;
    Лист.Cells(47,10).Value = ПараметрыПечати.ФИОРуководителя;
    Лист.Cells(47,26).Value = ПараметрыПечати.ФИОБухгалтера;
    Лист.Cells(49,10).Value = ПараметрыПечати.ФИООтветственный;
    Книга.Windows(1).Visible = Истина;
    
    
    Книга.Application.Visible=Истина;
  19. Ignat
    Offline

    Ignat Опытный в 1С

    Регистрация:
    18 мар 2012
    Сообщения:
    68
    Симпатии:
    0
    Баллы:
    26
    Добрый вечер. У меня есть определенный макет. Как его полностью скопировать в файл ексель? Чтобы шрифты были такие же и и т.д. Хочу сначала заполнить табличный документ как надо. А потом просто скопировать в файл. Так можно?
  20. nbIpKuH_BaH9I
    Offline

    nbIpKuH_BaH9I Модераторы Команда форума Модератор

    Регистрация:
    16 сен 2009
    Сообщения:
    6.978
    Симпатии:
    397
    Баллы:
    104
    Можно не париться и сразу сохранить в файл ексель...
    Код:
     ТабДок.Записать(ПутьКФайлу, "xls"); // Сохраним наш табличный документ в файл excel.
    

Поделиться этой страницей