Уважаемые профи! Помогите пожалуйста автоматизировать сохранение вновь созданной книги. Есть стороннее ПО из которого данные передаются в приложение Еxcel в формате книги .xls (2003). Поскольку при этом в окне Excel не подгружаются установленные надстройки (в том числе личная книга макросов - personal.xlsb) делаю вывод, что новое окно (приложение) Excel запускается в режиме автоматизации. Проблема описана вот в этой теме (архив): http://www.planetaexcel.ru/forum/index.php?PAGE_NAME=read&FID=8&TID=24346 Появились ли какие-то иные (новые) способы решения проблемы? Конкретно моя задача такая. При появлении новой книги с экспортированными из стороннего ПО данными, программно сделать следующее: Отследить появление книги и сохранить её, но уже в 2007 формате (.xlsx) с именем файла из ячейки A1 первого листа, по заданному мной пути, например H:\, и закрыть эту книгу и приложение Excel в котором она появилась. И зациклить это дело, т.е. при экспорте книга должна сразу без манипуляций со стороны пользователя сохраняться по требуемому пути и закрывать приложение Excel в котором она создана не трогая другие открытые книги (вообще во время работы этого цикла нужно чтобы была всегда открыта ещё 1 книга из файла) и далее по циклу. Задача облегчается тем, что имя (и путь к файлу) открытой книги не меняется и заранее известно ("AlwaysOpen"), а имя появляющихся книг всегда содержит текст "123" Желательно это сделать штатными средствами, доступными в Windows 7 + Excel 2007, через VBA (не нашел, что VBA такое позволяет), PowerShell, VBScript, JScript и т.п. Сам нашел такие варианты кода под похожие задачи: 1) VBScript, отслеживание нового процесса Excel и закрытие его, но мне не удалось модифицировать код под мою задачу, как я понял процесс нельзя привязать к COM-объекту Excel (поправьте если не прав):
Код
strComputer = "."
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colMonitoredProcesses = objWMIService.ExecNotificationQuery("SELECT * FROM __InstanceCreationEvent " _
& " WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'")
i = 0
Do While i = 0
Set objLatestProcess = colMonitoredProcesses.NextEvent
If objLatestProcess.TargetInstance.Name = "EXCEL.EXE" Then
objLatestProcess.TargetInstance.Terminate()
End If
Loop
2) VBScript, при одноразовом применении на уже созданной книге работает, но не удалось зациклить и добиться отслеживания вновь создаваемых книг и почему-то код закрывает все книги, а не только ту, где есть "123" в имени книги:
Код
On Error Resume Next
Dim objXL, WB
Set objXL = GetObject(, "Excel.Application")
Set WB = objXL.ActiveWorkbook
If Not TypeName(objXL) = "Empty" Then
If Not TypeName(WB) = "Nothing" Then
If Instr(1, objXL.ActiveWorkbook.Name, "123", vbTextCompare) > 0 then
objXL.ActiveWorkbook.SaveAs "H:\" & objXL.ActiveWorkbook.Worksheets(1).Cells(1, 1).Value & ".xlsx"
objXL.ActiveWorkbook.Close
objXL.Application.Quit
End If
End If
End If
Что вы используете из скриптовых языков в связке с excel? Хочу понять какой из них более удобен для автоматизации excel, мощнее, перспективнее и т.д, и соответственно какой изучать. VBScript как я понимаю загнулся, а жаль, ведь VBA и VBScript родственники, их удобнее учить вместе. Может кто-то использует более мощные вещи типа Python?
Есть 3 произвольно изменяющихся критерия крит1-3, тип всегда «волк» или «заяц». Нужно для каждого крит1 в случае наличия в столбце тип значения «волк» , разделить сумму волка на 300 и прибавить её к зайцу, но только если все 3 критерия для волка и зайца совпадают.
Если есть только волк, а соответствующего ему зайца нет, то ничего не делаем, то же самое с зайцем без волка.
Помогите пожалуйста избавиться от select в простеньком макросе. Везде, где это можно, кроме последней строки ActiveCell.Offset(1, 0).Select, т.к. нужно встать на данную ячейку.
Код
Sub last()
Dim iLastRow As Long
Dim rAbove As Range
Dim rBelow As Range
iLastRow = Cells(Rows.Count, 6).End(xlUp).Row
Cells(iLastRow + 1, 6).Select
ActiveCell.FormulaR1C1 = _
"=IF(RC[1]<0,""VVV"",""CCC"")"
Selection.Font.Bold = True
With Selection
.HorizontalAlignment = xlRight
End With
ActiveCell.Offset(0, 1).Select
Set rAbove = Range(ActiveCell.Offset(-1, 0), Cells(1, ActiveCell.Column))
Set rBelow = Range(ActiveCell.Offset(1, 0), ActiveCell.Offset(1, 0))
ActiveCell.Formula = "=" & rBelow.Address & "-SUM(" & rAbove.Address & ")"
ActiveCell.Offset(1, 0).Select
Selection.Font.Bold = True
End Sub
Еще вопрос, можно ли удалить столбцы не выделяя их:
Помогите пожалуйста с отбором суммы, которая идёт нарастающим итогом. В файле есть пояснения, сам принцип отбора не сложен, вот с реализацией проблема.
Необходимо из листа "данные" выбрать одного клиента (реализую потом через выпадающий список или ещё как-то, не суть). По этому клиенту нужно подставить его суммы, исходя из дат действия ставки рефинансирования ЦБ. Проблема в том, что есть ещё сроки по которому сумма изменяется нарастающим итогом. Т.е. отбор данных происходит исходя из пересечения 2-х диапазонов дат.
В примерах есть объяснение по выборочному суммированию по двум критериям http://www.planetaexcel.ru/tip.php?aid=79 Но что делать, если нужно указать в одном критерии _диапазон_ критериев? Так, исходя из условий примера по ссылке, как посчитать общую сумму всех заказов Чадова и Грирорьева для Копейки и Ашана?
Уважаемые форумчане нашли ответ! Спасибо всем кто участвовал в обсуждении исходной темы, привожу окончательные решения от ikki и МСН. Отдельное спасибо ikki за пользовательскую функцию (UDF)! В приложении отредактированный пример из tips с UDF от ikki и мой пример на котором и решалась задача.
___________________________________________________________________________ Текст UDF от ikki:
Function exelior(db As Range, criteria As Range, sSum As String) Dim aDB(), aCriteria(), aTemp(), i&, j&, jSum& Dim iDB1&, iDB2&, iCrit1&, iCrit2&, jDB1&, jDB2&, jCrit1&, jCrit2& Dim fDB As Boolean, fCrit As Boolean aDB = db.Value aCriteria = criteria.Value
ReDim aTemp(jCrit1 To jCrit2) For i = jCrit1 To jCrit2 For j = jDB1 To jDB2 If aCriteria(1, i) = aDB(1, j) Then aTemp(i) = j Exit For End If Next Next For j = jDB1 To jDB2 If sSum = aDB(1, j) Then jSum = j Next For i = iDB1 + 1 To iDB2 For j = jCrit1 To jCrit2 fCrit = False For k = iCrit1 + 1 To iCrit2 If aCriteria(k, j) <> Empty Then If aDB(i, aTemp(j)) = aCriteria(k, j) Then fCrit = True End If Next If Not fCrit Then GoTo nextRow Next 'Debug.Print i exelior = exelior + aDB(i, jSum) nextRow: Next End Function <EM><STRONG>Файл удален</STRONG> - велик размер - [<STRONG>МОДЕРАТОРЫ</STRONG>]</EM>