Друзья, с 2013 Excel нет возможности сохранять т.н. "рабочую область" в файл .XLW, однако открывать таковые, созданные в предыдущих версиях Excel, можно. Вопрос такой - каким образом, например макросом, сделать возможным сохранение рабочей области в новых версиях Excel?
Друзья, с 2013 Excel нет возможности сохранять т.н. "рабочую область" в файл .XLW, однако открывать таковые, созданные в предыдущих версиях Excel, можно. Вопрос такой - каким образом, например макросом, сделать возможным сохранение рабочей области в новых версиях Excel?iam_alex
А просто редактировать файл xlw, вписав в него нужные пути как-то можно?
Если вы готовы разобрать спецификацию, то вполне возможно. VBA позволяет работать с бинарными данными. Попробуйте. Если получится, то отпишитесь - вдруг кому ещё потребуется?
А просто редактировать файл xlw, вписав в него нужные пути как-то можно?
Если вы готовы разобрать спецификацию, то вполне возможно. VBA позволяет работать с бинарными данными. Попробуйте. Если получится, то отпишитесь - вдруг кому ещё потребуется?
Ребята, ну если в 2013 мелко-мягкие по каким-то своим соображениям убрали достаточно удобную, имхо, фичу, то ведь вполне можно сделать "протез", функционально заменяющий "ампутированный орган". Меня-то это не касается, т.к. на моих компах стоит Excel, её поддерживающий. Но ведь в принципе ничего сложного при вызове функции "Сохранить рабочую область" не делалось: 1. Предлагалось сохранить все открытые книги — нет проблем 2. Спрашивалось куда сохранять файл образа области — нет проблем 3. Сохранялся образ рабочей области в указанной папке в виде файла с расширением ".xlw" — а оно Вам принципиально, с каким расширением будет файл? Вам "шашечки" или "ехать"? А ".xlsm" Вас устроит? Тогда — нет проблем! В файле на единственном его листе начиная с ячейки А1 запишем ПОЛНЫЕ имена открытых файлов . А в модуле ЭтаКнига на событие Workbook_Open пропишем процедуру открытия всех файлов, перечисленных на листе. Ничего особенно сложного. P.S. В принципе в конце процедуры можно будет ещё и файл-протез закрыть. Всё это вполне можно оформить надстройкой.
При открытии этого нашего файла-протеза, заменяющего ".xlw", НА ЛЮБОМ компьютере, даже не "оборудованном" надстройкой, а лишь бы макросы были разрешены, будет выполняться процедура Workbook_Open.
Ребята, ну если в 2013 мелко-мягкие по каким-то своим соображениям убрали достаточно удобную, имхо, фичу, то ведь вполне можно сделать "протез", функционально заменяющий "ампутированный орган". Меня-то это не касается, т.к. на моих компах стоит Excel, её поддерживающий. Но ведь в принципе ничего сложного при вызове функции "Сохранить рабочую область" не делалось: 1. Предлагалось сохранить все открытые книги — нет проблем 2. Спрашивалось куда сохранять файл образа области — нет проблем 3. Сохранялся образ рабочей области в указанной папке в виде файла с расширением ".xlw" — а оно Вам принципиально, с каким расширением будет файл? Вам "шашечки" или "ехать"? А ".xlsm" Вас устроит? Тогда — нет проблем! В файле на единственном его листе начиная с ячейки А1 запишем ПОЛНЫЕ имена открытых файлов . А в модуле ЭтаКнига на событие Workbook_Open пропишем процедуру открытия всех файлов, перечисленных на листе. Ничего особенно сложного. P.S. В принципе в конце процедуры можно будет ещё и файл-протез закрыть. Всё это вполне можно оформить надстройкой.
При открытии этого нашего файла-протеза, заменяющего ".xlw", НА ЛЮБОМ компьютере, даже не "оборудованном" надстройкой, а лишь бы макросы были разрешены, будет выполняться процедура Workbook_Open.Alex_ST
С уважением, Алексей MS Excel 2003 - the best!!!
Сообщение отредактировал Alex_ST - Пятница, 20.01.2017, 21:46
А в модуле ЭтаКнига на событие Workbook_Open пропишем процедуру открытия всех файлов, перечисленных на листе. Ничего особенно сложного.
Это вполне приемлемое решение, т.к. нам "ехать")) Вот только, если это не сложно для людей, разбирающихся в написании макросов, может быть помогут?) т.к. для меня это - никак(
А в модуле ЭтаКнига на событие Workbook_Open пропишем процедуру открытия всех файлов, перечисленных на листе. Ничего особенно сложного.
Это вполне приемлемое решение, т.к. нам "ехать")) Вот только, если это не сложно для людей, разбирающихся в написании макросов, может быть помогут?) т.к. для меня это - никак(iam_alex
Николай, это-то как раз проще всего. Но сначала нужно: 1) по нажатию на кнопку "Сохранить рабочую область..." в новом файле на листе создать список открытых - это совсем не сложно 2) в модуле ЭтаКнига файла прописать этот (или аналогичный) код обработки события - это не очень сложно, но выше типового уровня, т.к. требует умения работать с VBProject (пример есть у Уокенбаха) 3) запросить куда и под каким именем сохранять этот файл - не сложно 4) сохранить файл - совсем просто.
Для тех, кто возьмётся доделывать: Вот утилита, которая скопированный в буфер обмена с листа VBE текст нужных процедур преобразует в стринг, добавляемый в .CodeModule и помещает его обратно в буфер обмена (публиковал ЗДЕСЬ)
[vba]
Код
' =========== Утилита подготовки стрингов для вставки в .CodeModule ================= Private Sub Get_Code_String() ' преобразование текстов кодов процедур в стринги ' текст кодов процедур, скопированный в буфер обмена, преобразовать в стринги в соответствии с правилами VBE и поместить в буфер обмена Dim sCode$, sText$, sString$ With GetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}"): .GetFromClipBoard: sCode = .GetText: End With ' получить текст кода процедур из буфера обмена sText = Replace(sCode, """", """""") ' замена " на "" sString = """" & Replace(sText, vbCrLf, """ & vbCrLf & _" & vbCrLf & """") & """" ' замена возвратов каретки на их коды в стринге 'Debug.Print sText With GetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}"): .SetText sString: .PutInClipBoard: End With ' поместить текст стринга в буфер обмена End Sub
[/vba]
Николай, это-то как раз проще всего. Но сначала нужно: 1) по нажатию на кнопку "Сохранить рабочую область..." в новом файле на листе создать список открытых - это совсем не сложно 2) в модуле ЭтаКнига файла прописать этот (или аналогичный) код обработки события - это не очень сложно, но выше типового уровня, т.к. требует умения работать с VBProject (пример есть у Уокенбаха) 3) запросить куда и под каким именем сохранять этот файл - не сложно 4) сохранить файл - совсем просто.
Для тех, кто возьмётся доделывать: Вот утилита, которая скопированный в буфер обмена с листа VBE текст нужных процедур преобразует в стринг, добавляемый в .CodeModule и помещает его обратно в буфер обмена (публиковал ЗДЕСЬ)
[vba]
Код
' =========== Утилита подготовки стрингов для вставки в .CodeModule ================= Private Sub Get_Code_String() ' преобразование текстов кодов процедур в стринги ' текст кодов процедур, скопированный в буфер обмена, преобразовать в стринги в соответствии с правилами VBE и поместить в буфер обмена Dim sCode$, sText$, sString$ With GetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}"): .GetFromClipBoard: sCode = .GetText: End With ' получить текст кода процедур из буфера обмена sText = Replace(sCode, """", """""") ' замена " на "" sString = """" & Replace(sText, vbCrLf, """ & vbCrLf & _" & vbCrLf & """") & """" ' замена возвратов каретки на их коды в стринге 'Debug.Print sText With GetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}"): .SetText sString: .PutInClipBoard: End With ' поместить текст стринга в буфер обмена End Sub
Появилось немного свободного времени. Набросал нужную процедуру:
[vba]
Код
Sub Get_WorkSpace() Dim WBk As Workbook, i% Dim sFileName$: sFileName = "WorkSpace [" & Format(Now, "yyyy/mm/dd hh-mm'ss''") & "]" Dim sCode$: sCode = "Private Sub Workbook_Open()" & vbCrLf & _ " Dim rCell As Range" & vbCrLf & _ " For Each rCell In Sheets(1).Range(""a1:a100"")" & vbCrLf & _ " If rCell.Value <> """" Then Workbooks.Open Filename:=rCell.Value" & vbCrLf & _ " Next" & vbCrLf & _ " ThisWorkbook.Close" & vbCrLf & _ "End Sub" With Application.Workbooks.Add For Each WBk In Workbooks If Split(WBk.Name, ".")(0) <> "Personal" And WBk.Name <> .Name Then .Sheets(1).Cells(i + 1, 1).Value = WBk.FullName: i = i + 1 End If Next WBk With .VBProject.VBComponents(1).CodeModule .InsertLines .CountOfDeclarationLines + 1, sCode End With End With End Sub
[/vba]
Размещаете её в Personal. Делаете кнопку для вызова. Всё, вроде, работает. Можно бы доделать, но и без этого работает: - добавить предложение сохранить все открытые файлы - добавить диалог сохранения файла
Появилось немного свободного времени. Набросал нужную процедуру:
[vba]
Код
Sub Get_WorkSpace() Dim WBk As Workbook, i% Dim sFileName$: sFileName = "WorkSpace [" & Format(Now, "yyyy/mm/dd hh-mm'ss''") & "]" Dim sCode$: sCode = "Private Sub Workbook_Open()" & vbCrLf & _ " Dim rCell As Range" & vbCrLf & _ " For Each rCell In Sheets(1).Range(""a1:a100"")" & vbCrLf & _ " If rCell.Value <> """" Then Workbooks.Open Filename:=rCell.Value" & vbCrLf & _ " Next" & vbCrLf & _ " ThisWorkbook.Close" & vbCrLf & _ "End Sub" With Application.Workbooks.Add For Each WBk In Workbooks If Split(WBk.Name, ".")(0) <> "Personal" And WBk.Name <> .Name Then .Sheets(1).Cells(i + 1, 1).Value = WBk.FullName: i = i + 1 End If Next WBk With .VBProject.VBComponents(1).CodeModule .InsertLines .CountOfDeclarationLines + 1, sCode End With End With End Sub
[/vba]
Размещаете её в Personal. Делаете кнопку для вызова. Всё, вроде, работает. Можно бы доделать, но и без этого работает: - добавить предложение сохранить все открытые файлы - добавить диалог сохранения файлаAlex_ST
С уважением, Алексей MS Excel 2003 - the best!!!
Сообщение отредактировал Alex_ST - Понедельник, 23.01.2017, 22:45
Друзья! Спасибо, что откликнулись!!)) Прописал процедуру в Personal, добавил кнопку на панель - запустил (пути прописались) - сохранил книгу как xlsm - открыл с поддержкой макросов - РАБОТАЕТ!!!)))
Единственный момент (вопрос) - при срабатывании процедуры прописываются также пути:
Друзья! Спасибо, что откликнулись!!)) Прописал процедуру в Personal, добавил кнопку на панель - запустил (пути прописались) - сохранил книгу как xlsm - открыл с поддержкой макросов - РАБОТАЕТ!!!)))
Единственный момент (вопрос) - при срабатывании процедуры прописываются также пути:
iam_alex, Ну, во-первых разберитесь, почему у Вас в XLSTART лежат и сам файл PERSONAL.XLSB, и его копия? Может быть был когда-то крэш Excel'я и записалась резервная копия? Во-вторых, в коде явно прописано, что добавлять имя в список нужно только если[vba]
Код
If Split(WBk.Name, ".")(0) <> "Personal"
[/vba]поэтому PERSONAL.XLSB сохраняться не должно... Ну, можно попробовать поменять на[vba]
Код
If Not WBk.Name Like "*\XLSTART\Personal*"
[/vba]тогда уж точно не должно. В общем, пробуйте допиленное со всякими доработками:
[vba]
Код
Private Sub Save_WorkSpace() ' '--------------------------------------------------------------------------------------- ' Procedure : Save_WorkSpace ' Author : Alex_ST ' Post_URL : http://www.excelworld.ru/forum/2-31951-207599-16-1485242663 ' DateTime : 24.01.2017, 10:24 ' Purpose : Сохранение рабочей области ' Notes : "протез" ампутированной функции Excel-2013 '--------------------------------------------------------------------------------------- Dim sTitle$: sTitle = "Сохранение рабочей области..." If MsgBox("Перед сохранением рабочей области" & vbCr & "необходимо сохранить все открытые файлы Excel." & vbCr & _ "Сохранить файлы и продолжить?", vbYesNo + vbQuestion, sTitle) = vbNo Then Exit Sub Dim sFileName$: sFileName = "WorkSpace (" & Format(Now, "yyyy.mm.dd hh-mm'ss''") & ").xls" Dim sCode$: sCode = "Private Sub Workbook_Open()" & vbCrLf & _ " Dim rCell As Range" & vbCrLf & _ " For Each rCell In Sheets(1).Range(""a1:a100"")" & vbCrLf & _ " If rCell.Value <> """" Then Workbooks.Open Filename:=rCell.Value" & vbCrLf & _ " Next" & vbCrLf & _ "' ThisWorkbook.Close" & vbCrLf & _ "End Sub" Dim WBk As Workbook, i% Dim WSWBk As Workbook: Set WSWBk = Application.Workbooks.Add With WSWBk For Each WBk In Workbooks If Not WBk.FullName Like "*\XLSTART\Personal*" And WBk.Name <> .Name Then .Sheets(1).Cells(i + 1, 1).Value = WBk.FullName: i = i + 1 If Not WBk.Saved Then WBk.Save End If Next WBk With .VBProject.VBComponents(1).CodeModule .InsertLines .CountOfDeclarationLines + 1, sCode End With End With With Application.FileDialog(msoFileDialogSaveAs) .InitialFileName = sFileName: .Title = sTitle: .ButtonName = "Сохранить": .InitialView = msoFileDialogViewLargeIcons If .Show = 0 Then Exit Sub ' если нажали "Отмена", то .Show = 0 Application.DisplayAlerts = False WSWBk.SaveAs FileName:=.SelectedItems(1) Application.DisplayAlerts = True End With 'Application.Quit End Sub
[/vba]
После отладки апостроф в стринге[vba]
Код
"' ThisWorkbook.Close" & vbCrLf & _
[/vba]можно убрать. Тогда файл сохранённой рабочей области закроется сам после того, как откроются все нужные книги
iam_alex, Ну, во-первых разберитесь, почему у Вас в XLSTART лежат и сам файл PERSONAL.XLSB, и его копия? Может быть был когда-то крэш Excel'я и записалась резервная копия? Во-вторых, в коде явно прописано, что добавлять имя в список нужно только если[vba]
Код
If Split(WBk.Name, ".")(0) <> "Personal"
[/vba]поэтому PERSONAL.XLSB сохраняться не должно... Ну, можно попробовать поменять на[vba]
Код
If Not WBk.Name Like "*\XLSTART\Personal*"
[/vba]тогда уж точно не должно. В общем, пробуйте допиленное со всякими доработками:
[vba]
Код
Private Sub Save_WorkSpace() ' '--------------------------------------------------------------------------------------- ' Procedure : Save_WorkSpace ' Author : Alex_ST ' Post_URL : http://www.excelworld.ru/forum/2-31951-207599-16-1485242663 ' DateTime : 24.01.2017, 10:24 ' Purpose : Сохранение рабочей области ' Notes : "протез" ампутированной функции Excel-2013 '--------------------------------------------------------------------------------------- Dim sTitle$: sTitle = "Сохранение рабочей области..." If MsgBox("Перед сохранением рабочей области" & vbCr & "необходимо сохранить все открытые файлы Excel." & vbCr & _ "Сохранить файлы и продолжить?", vbYesNo + vbQuestion, sTitle) = vbNo Then Exit Sub Dim sFileName$: sFileName = "WorkSpace (" & Format(Now, "yyyy.mm.dd hh-mm'ss''") & ").xls" Dim sCode$: sCode = "Private Sub Workbook_Open()" & vbCrLf & _ " Dim rCell As Range" & vbCrLf & _ " For Each rCell In Sheets(1).Range(""a1:a100"")" & vbCrLf & _ " If rCell.Value <> """" Then Workbooks.Open Filename:=rCell.Value" & vbCrLf & _ " Next" & vbCrLf & _ "' ThisWorkbook.Close" & vbCrLf & _ "End Sub" Dim WBk As Workbook, i% Dim WSWBk As Workbook: Set WSWBk = Application.Workbooks.Add With WSWBk For Each WBk In Workbooks If Not WBk.FullName Like "*\XLSTART\Personal*" And WBk.Name <> .Name Then .Sheets(1).Cells(i + 1, 1).Value = WBk.FullName: i = i + 1 If Not WBk.Saved Then WBk.Save End If Next WBk With .VBProject.VBComponents(1).CodeModule .InsertLines .CountOfDeclarationLines + 1, sCode End With End With With Application.FileDialog(msoFileDialogSaveAs) .InitialFileName = sFileName: .Title = sTitle: .ButtonName = "Сохранить": .InitialView = msoFileDialogViewLargeIcons If .Show = 0 Then Exit Sub ' если нажали "Отмена", то .Show = 0 Application.DisplayAlerts = False WSWBk.SaveAs FileName:=.SelectedItems(1) Application.DisplayAlerts = True End With 'Application.Quit End Sub
[/vba]
После отладки апостроф в стринге[vba]
Код
"' ThisWorkbook.Close" & vbCrLf & _
[/vba]можно убрать. Тогда файл сохранённой рабочей области закроется сам после того, как откроются все нужные книгиAlex_ST
С уважением, Алексей MS Excel 2003 - the best!!!
Сообщение отредактировал Alex_ST - Вторник, 24.01.2017, 13:18
теперь при выполнении макроса предлагается сначала сохранить все открытые книги
доходит до сохранения файла (открывается диалоговое окно, присваивается имя типа WorkSpace (2017/01/24 15-46'31'') - говорит недопустимое имя файла, оставляю только WorkSpace, выбираю xlsm, вылазит ошибка 1004 - расширение нельзя использовать с выбранным типом файла, жму Debug - показывает на строку WSWBk.SaveAs Filename:=.SelectedItems(1)
теперь при выполнении макроса предлагается сначала сохранить все открытые книги
доходит до сохранения файла (открывается диалоговое окно, присваивается имя типа WorkSpace (2017/01/24 15-46'31'') - говорит недопустимое имя файла, оставляю только WorkSpace, выбираю xlsm, вылазит ошибка 1004 - расширение нельзя использовать с выбранным типом файла, жму Debug - показывает на строку WSWBk.SaveAs Filename:=.SelectedItems(1)iam_alex
Sub CloseAllWorkbooks3() ' закрываем все книги, кроме текущей (активной), С СОХРАНЕНИЕМ изменений Dim wb As Workbook: Application.ScreenUpdating = False For Each wb In Workbooks ' перебираем все открытые книги If wb.Windows(1).Visible = True Then ' закрываем с сохранением только изменённые файлы wb.Close (Not wb.Saved) ' ранее сохранённые файлы просто закрываются End If Next wb Application.Quit End Sub
возможно из него можно добавить ту (наподобие) часть, которая сохраняет только измененные файлы, а остальные не трогает.
но эту уже из разряда хотелок)) хотя может и посчитаете их полезными) и еще одна хотелка-доработка - если при уже открытых книгах из списка я снова жму открыть, то вполне резонно excel ругается, что не может открыть уже открытые книги, при нажатии на "нет" макрос выдает ошибку. может стоит проверять открыта книга или нет... например могут быть случаи, когда хочешь открыть другую рабочую область, в которой часть файлов совпадает с уже открытыми
а еще я пользуюсь таким макросом:
Sub CloseAllWorkbooks3() ' закрываем все книги, кроме текущей (активной), С СОХРАНЕНИЕМ изменений Dim wb As Workbook: Application.ScreenUpdating = False For Each wb In Workbooks ' перебираем все открытые книги If wb.Windows(1).Visible = True Then ' закрываем с сохранением только изменённые файлы wb.Close (Not wb.Saved) ' ранее сохранённые файлы просто закрываются End If Next wb Application.Quit End Sub
возможно из него можно добавить ту (наподобие) часть, которая сохраняет только измененные файлы, а остальные не трогает.
но эту уже из разряда хотелок)) хотя может и посчитаете их полезными) и еще одна хотелка-доработка - если при уже открытых книгах из списка я снова жму открыть, то вполне резонно excel ругается, что не может открыть уже открытые книги, при нажатии на "нет" макрос выдает ошибку. может стоит проверять открыта книга или нет... например могут быть случаи, когда хочешь открыть другую рабочую область, в которой часть файлов совпадает с уже открытымиiam_alex
Сообщение отредактировал iam_alex - Вторник, 24.01.2017, 12:26
Явно недопустимые символы / Должно выводить дату с разделителем дня-месяца-года через точку! Типа WorkSpace (2017.01.24 15-46'31'') Может быть у Вас что-то в системных и регионалных установках не так прописано? Попробуйте при любой открытой книге Excel нажать Alt+F11 , потом Ctrl+G В открывшееся окно Immediate Window введите текст:[vba]
Код
? Format(Now, "yyyy/mm/dd hh-mm'ss''")
[/vba]В ответ должны получить что-то типа:[vba]
Код
2017.01.24 13-09'50''
[/vba] Если же всё-таки разделители будут на ТОЧКА, а СЛЭШ, то попробуйте там же ввести[vba]
Код
? Format(Now, "yyyy.mm.dd hh-mm'ss''")
[/vba]если получите нормальный вид с ТОЧКАМИ между годом, месяцем и днём, то поправьте соответственно в задании переменной: вместо[vba]
[/vba]Или если лень, просто перекачайте процедуру из моего предыдущего поста - я там поправил. ----------------------------- А не видно её в макросах потому, что процедура декларирована как Private Sub , а не просто Sub как раз для того, чтобы не "светилась" в макросах Чтобы назначить её на кнопку удалите слово Private . Она появится в Макросах. После назначения можете его поставить обратно. ---------
Что там мелко-мягкие нахимичили в 2013-ом? С чего это вдруг даётся такое имя ???
Явно недопустимые символы / Должно выводить дату с разделителем дня-месяца-года через точку! Типа WorkSpace (2017.01.24 15-46'31'') Может быть у Вас что-то в системных и регионалных установках не так прописано? Попробуйте при любой открытой книге Excel нажать Alt+F11 , потом Ctrl+G В открывшееся окно Immediate Window введите текст:[vba]
Код
? Format(Now, "yyyy/mm/dd hh-mm'ss''")
[/vba]В ответ должны получить что-то типа:[vba]
Код
2017.01.24 13-09'50''
[/vba] Если же всё-таки разделители будут на ТОЧКА, а СЛЭШ, то попробуйте там же ввести[vba]
Код
? Format(Now, "yyyy.mm.dd hh-mm'ss''")
[/vba]если получите нормальный вид с ТОЧКАМИ между годом, месяцем и днём, то поправьте соответственно в задании переменной: вместо[vba]
[/vba]Или если лень, просто перекачайте процедуру из моего предыдущего поста - я там поправил. ----------------------------- А не видно её в макросах потому, что процедура декларирована как Private Sub , а не просто Sub как раз для того, чтобы не "светилась" в макросах Чтобы назначить её на кнопку удалите слово Private . Она появится в Макросах. После назначения можете его поставить обратно. ---------Alex_ST
С уважением, Алексей MS Excel 2003 - the best!!!
Сообщение отредактировал Alex_ST - Вторник, 24.01.2017, 13:54