Страницы: Пред. 1 2
RSS
Возможно ли переназначить WorkSheets(b) в WorkSheets(c) ?
 
Цитата
Юрий М написал: Может быть отталкиваться от кодового имени листа?
Может чего недопонимаю. Что это за имя? Номер листа в объект эксплорере? Так он при переходе из книги в книгу скачет и опять же, непонятно, как реализовать конструкцию set workbooks(a).worksheets(b)=workbooks(h).worksheets(b)?

Цитата
vikttur написал: А как Вы его [лист] в переменную разместите - это другой вопрос.
Именно этот другой вопрос и озвучен в теме! А как уж передать, если есть переменная... вопрос не ставился.

Цитата
Irregular Expression написал: Вы сами озвучили проблему своей программы: излишняя сложность и связанность кода,
Видео примера работы программы привел. Вы знаете, как реализовать это проще, раз ведете речь об ИЗЛИШНЕЙ сложности?
Изменено: Neufazendnik - 22.06.2018 22:22:41
 
Цитата
Ігор Гончаренко написал:
см. соообщение #2, опишите не дебри, в которые Вы забрались в попытках решить задачу, а опишите задачу, которую нужно решить:- макрос должен обработать определенный лист,- несколько определенных листов,- пользователь должен УКАЗАТЬ какие листы обработать, - Ваш вариант
Нет макроса. Есть цепь взаимосвязанных макросов, которых одновременно отрабатывает по цепочке друг за другом десятки.
Поэтому говорить о макросе, который должен что-то делать - слишком абстрактно. Каждый из макросов что-то делает. Каждый делает по разному. Один вычисляет имена листов по одним правилам. Другой по другим. Т.к. Работают они с разными группами листов. Третий макрос передает имя вычисленных листов в четврертый. Четвертый через них выбирает какие-то данные, которые чтобы отобразить, нужно раскрыть ссылки на другие данные. Те в свою очередь могут храниться на третьих листах, имена которых тоже надо вычислить..
Пользователь указывает тип таблицы, которую он хочет видеть и группу данных (раздел данных) которые хочет видеть в этой таблице. При этом, указывает он это во вспомогательных таблицах, которые динамически перерисовываются по мере  того, какую информацию предпочитает увидеть пользователь. Программа обрабатывает каждое движение пользователя и реагирует на каждое смещение от ячейки к ячейке. Это не набор статических таблиц. Это динамическая перерисовка содержимого. Смотрите видео!
 
Neufazendnik, В принципе Вам показали необходимое (пример от vikttur). То что у Вас сейчас в коде используется другая конструкция обращения, так ее нужно переделать. То что искомый лист может быть где угодно, то в любом случае его нужно сначала определить или найти, да хоть путем перебора - то есть идентифицировать, а потом передать как переменную во все необходимые подпрограммы для дальнейших действий.
Изменено: skais675 - 22.06.2018 22:32:11
 
Цитата
Ігор Гончаренко написал:
Вы перестанете рассказывать о Вашем решении задачи, а начнете рассказывать о самой задаче - появится хоть какой-то шанс...
Я отвечаю на те вопросы, которые мне задают люди, пытающиеся для себя что-то выяснить.
Если Вы пытваетесь выяснить саму задачу, то сформулирую ее так: Реализовать то, что на языке VBA было бы записано так:
set workbooks(a).worksheets(b)=workbooks(h).worksheets(b)
 
skais675, vikttur не показал ничего нового, кроме классики работы с листами. Меня просили привести пример подпрограммы. Я его привел. Вы его открывали? А vikttur? В нем давно реализовано то, что предлагает сделать vikttur.
Еще раз суть проблемы: Из версии в версию виндовс переписываются целые пакеты dll, включая даже реализацию досовских команд. Ни кто не вникает в то, понадобятся они или нет конкретному пользователю. Их просто тупо копируют для совместимости. Вот в моей программе нечто подобное. Есть громадная гора процедур, которые могли бы пригодиться. Делались они на протяжении многих лет. Код их писался из предположения, что все листы базы данных размещены в одном единственном файле. Теперь, по прошествии многих лет потребовалось сделать распределенную БД и часть листов вывести на отдельное от этого файла хранение. Но этом вызывает необходимость Переписывать весь многолетний труд наработок из процедур заново. И перепроверять - это работа еще на многие годы. Эта работа может быть полностью устранена реализацией банальной конструкции: set workbooks(a).worksheets(b)=workbooks(h).worksheets(b)
Весь вопрос в том, как такую конструкцию реализовать?
 
Цитата
Neufazendnik написал:
Что это за имя? Номер листа в объект эксплорере? Так он при переходе из книги в книгу скачет
В окне свойств самая верхняя строка. И не скачет.
Но не знаю, поможет ли Вам это...
 
workbooks(a).worksheets(b) это какой-то конкретный лист в книге workbooks(a)
НЕЛЬЗЯ листу книги присвоить лист из другой книги
можнно
Код
workbooks(a).worksheets(b).cells.value=workbooks(h).worksheets(b).cells.value

значениям ячеек одного листа присвоить значения ячеек из другого листа
можно
Код
Set WS1 = workbooks(a).worksheets(b)
Set WS2 = workbooks(h).worksheets(b)
Set WS2 = WS1

переменной присвоить ссылку на лист, а потом присвоить это другой переменной
но зачем все это???
ладно, удачи!
Изменено: Ігор Гончаренко - 22.06.2018 23:05:53
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Neufazendnik,Может как вариант, вместо подстановки - отсутствующие листы копировать в нужную книгу обрабатывать по Вашему коду и потом обратно возвращать на место.
Изменено: skais675 - 22.06.2018 22:58:09
 
Цитата
Юрий М написал:
В окне свойств самая верхняя строка. И не скачет.
Спасибо. Включился. Надо обмозговать. Может как раз поможет. Я никогда не использовал это свойство.
Машинально поменять весь код на работу с этим свойством вместо видимых имен листов мне кажется задача куда более простая, чем вникать в код и переделывать его.
Подумаю.
 
Не поможет. Обращение к внутреннему имени листа из другой книги не получится...
Была такая проблема, даже тему создавал...

Хотя могу ошибаться и есть обходной путь.
 
Цитата
vikttur написал:
есть обходной путь
Может здесь? )
 
Спасибо. Надо взять на заметку.
 
Ігор Гончаренко, оба преждложенных варианта не подойдут.
Вариант с копированием и так реализован в виде тупого переноса листа из файла в файл. Этот вариант сейчас работает в качестве затычки и временного решения моей проблемы. Но это опять же перенос туда-сюда. Не желаю я ничего таскать из книги в книгу. Это отжерает ресурсы - процессорное время. Ваш вариант еще медлительнее, чем перетаскивания листа целиком, ИМХО.
Вариант второй с тиражированием ссылки говорит о Вашем непонимании задачи.
Большинство процедур у меня работали с нотацией Set WS1 = workbooks(a).worksheets(b) . В ней "a" было константно на протяжении всего исполнения процедуры. Т.е помимо указанной ссылки через workbooks(a) в них было определено еще куча всего.
В новых условиях для отдельных видов данных (т.е только для части кода) "a" перестает быть константой. (вплоть до того, что в одной и той же строке кода в цикле к примеру "а" будет разным, а в соседних строках кода по логике подпрограммы будет использоваться, словно это константное только на один единственно возможный предопределенный файл. Таким образом возникает конфликт присвоения. Если одно и то же "а" останется по прежнему константным в процессе исполнения всего кода подпрограммы, то часть операторов Set Q = workbooks(a).worksheets(b) наприсваивают что-то не то.  С другой стороны, если их делать не константными, то что-то не то наприсваивается в другом месте этой же подпрограммы. Короче, как ни крути, а WS1 = workbooks(a).worksheets(b) без альяса не будет работать корректно. А как запузырить этот альясный путь на данные - ломаю голову. По варианту второму сформулировал путано. Мне нужно подумать, как почетче и лаконичнее на конкретном примере показать, что имею ввиду.
Изменено: Neufazendnik - 22.06.2018 23:40:51
 
Так, коллеги, решение моего вопроса кажется нашлось.
У меня есть переменная ge49, которая хранит в себе имя книги с базой данных. Соответственно, во всех моих подпрограммах и старых и новых используется нотация workbooks(ge49).worksheets(b) или производная от нее "c", определенная через set c = workbooks(ge49).worksheets(b)
Мне достаточно создать функцию L(b), возвращающую объект workbook. Т.е эта функция будет мне возвращать объект - книгу хранения листа базы данных с именем b.
С появлением такой функции, абсолютно весь код моего модуля, содержащий нотацию workbooks(ge49).worksheets(b) автозаменой меняю на код L(b).worksheets(b)
И тогда поставленная задача выполнена. Мне не придется разбираться с кодом сотен процедур. Он поменяется автоматически и при этом основная задача будет рещена. Листы с данными будут вызываться из тех книг, в которую они перенесены!
 
Цитата
Neufazendnik написал:
Вариант второй с тиражированием ссылки говорит о Вашем непонимании задачи.
да я криком кричу, что задачу не понимаю и не пойму ее до тех пор пока Вы не снизойдете до обьяснений задачи
мне интересна задача в чистом виде, и совершенно не интересны дебри, в которые Вы забрались решая ее.
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Цитата
Neufazendnik написал: Мне достаточно создать функцию L(b), возвращающую объект workbook. Т.е эта функция будет мне возвращать объект - книгу хранения листа базы данных с именем b.
Пожалуйста
Код
Function L(iSh$) As Workbook
    Set L = Worksheets(iSh).Parent
End Function

Sub TestL()
Dim sh As Worksheet, wb As Workbook
    Set sh = ActiveSheet
    Set wb = L(sh.Name)
    MsgBox "Лист '" & sh.Name & "' содержится в книге '" & wb.Name & "'"
End Sub
Согласие есть продукт при полном непротивлении сторон
 
Sanja, Не, не все так просто в нашем королевстве. Но все же ваша заготовка безусловно будет в основе этой реализации. Спасибо.
Имя листа передается в процедуру как текстовый параметр же. Этот лист вовсе не активен и вовсе не в текущей книге может находиться, а в отдельном файле, существование которого еще предстоит проверить!
Так что процедура должна быть завязана с FSO и с правилами размещения данных в отдельных файлах, принятыми для хранения моей БД.
Но проблемы тут нет никакой. Эту процедуру я сгондоблю. Сложностей не вижу.
Изменено: Neufazendnik - 23.06.2018 09:36:46
 
Цитата
Neufazendnik написал: Этот лист вовсе не активен и вовсе не в текущей книге может находиться
Переменной sh имя активного лист присвоено для примера.
Цитата
Neufazendnik написал: Не, не все так просто
Разве не Вы это написали?
Цитата
Neufazendnik написал: Мне достаточно...и далее по тексту.
Вариант. Возвращает Книгу, в которой содержится Лист с именем, переданным аргументом iSh. Поиск идет во все открытых книгах
Код
Function L(iSh$) As Workbook
Dim wb As Workbook
Dim sh As Worksheet
On Error Resume Next
For Each wb In Workbooks
    Set sh = wb.Worksheets(iSh)
    If Not sh Is Nothing Then
        Set L = Worksheets(iSh).Parent
        Exit For
    End If
Next
End Function
 
Согласие есть продукт при полном непротивлении сторон
 
Sanja,
Цитата
Sanja написал:
Поиск идет во все открытых книгах
Вот здесь то собачка и порылась. Я не планирую заранее открывать все файлы базы данных. Большая часть из них для конкрентого сеанса работы конкретного пользователя открывать не нужно. К тому же это занимает время как на открытие, так и на последующее закрытие в конце работы, не говоря об отожранных у системы ресурсах. Держать открытыми пару десятков файлов по 4 мега - не самое разумное концептуальное решение.
Я вообще не буду их открывать явно, а предполагаю работать с ними через getobject и только с нужными файлами (по запросу) а не сразу со всеми.
Изменено: Neufazendnik - 23.06.2018 09:56:24
 
Цитата
Neufazendnik написал: предполагаю работать с ними через getobject
Вариант. Аргументы - Полный путь к папке с файлами и Имя искомого листа
Код
Function WB_DataBase(iPath, iSh) As Workbook
Dim iWb As Object, sh As Worksheet
Application.ScreenUpdating = False
Application.EnableEvents = False
On Error Resume Next
    iFile = Dir(iPath & "*.xls*")
    Do While iFile <> ""
        Set iWb = GetObject(iPath & iFile)
        Set sh = iWb.Worksheets(iSh)
        If Not sh Is Nothing Then
            Set WB_DataBase = Workbooks(iWb.Name)
            Exit Do
        End If
        iWb.Close False
        iFile = Dir
    Loop
Application.EnableEvents = True
Application.ScreenUpdating = True
End Function

'пример использования
Sub TestL()
Dim sh As Worksheet, wb As Workbook
sPath = "d:\DEVELOP\"
MySheet = "Бланк"
Set wb = WB_DataBase(sPath, MySheet)
MsgBox "Лист '" & MySheet & "' содержится в книге '" & wb.Name & "'"
wb.Close False
End Sub
Вот это не совсем понятно
Цитата
Neufazendnik написал: только с нужными файлами (по запросу)
Согласие есть продукт при полном непротивлении сторон
 
Sanja, Спасибо. Код буду смотреть. Бегло - в принципе то, что требуется.
Цитата
Sanja написал:
Вот это не совсем понятно
Например есть 95 тип данных - (прайс-листы), данные которого распределнены на 4 однотипных файла c именами 95U0, 95U1 .. 95U3. К примеру, пользователь работает только с записями, сосредоточившимися в пределах последнего файла 95U3. Это выясняется уже в тот момент, когда пользователь задал команду отрисовать скажем 5 элементов данного типа по ссылке. Программа вычисляет, что записи по всем пяти ссылкам размещена в пределах 95U3. Поэтому стоит задача использовать вместо некогда фигурировавшего в старых процедурах кода Workbooks(ge49).Worksheets("95") ссылочную переменную, ссылающуюся на лист с именем "95U3" в файле с одноименным названием! Соответственно этот файл и нужно либо связывать с программой через getobject либо загружать явно в текущий экземпляр оболочки эксель.
Другой пример. Пользователь в текущем сеансе работы использовал всего 4-5 видов таблиц = 4-5 типов. соответственно ему нужно для работы условно 4-5 файлов (может и больше, если какой-то из типов хранит много информации и она распределена на несколько файдов как в некотором примере) Но это все очень мало в сравнении с тем, что база данных может в себе размещать информацию по сотням других типов. Ее не требуется не читать не тем более подгружать заведомо в текущий экземпляр Эксель.
Изменено: Neufazendnik - 23.06.2018 11:11:21
 
Sanja из заголовка вашей функции путь в качестве параметра убираем. Он будет передаваться побочным эффектом через переменные уровня модуля, т.к путь на базу данных неизменен для всех вызовов. В остальном все резонно, кроме...
Цитата
Sanja написал:
wb.Close False
вот это отягощенице как-то мне не очень нравится. Его придется вставлять в код везде, где была подмена Workbook на WB_DataBase.
Пожалуй будет введен массив уровня модуля, содержащий перечень объектных переменных, сгенерированных WB_DataBase.
И в конце работы нужно просто запускать отдельную процедуру, которая закрывает все открытые через WB_DataBase объекты.
Изменено: Neufazendnik - 23.06.2018 11:34:30
 
Давайте в Курилку. Создайте тему о форматировании, правильном написании кода. Перенесу туда последние сообщения их этой темы

Других прошу временно воздержаться от ответов. Не добавляйте работы.
 
Цитата
vikttur написал:
Если обсуждение вызвало интерес - создать тему. Или в Курилке - если вот так потрепаться, или здесь - если конкретный вопрос.
Да, в курилке тему создам. Но нужно чуть подготовиться. Позже. Вы правильно поняли, есть и интерес и ... на самом деле Вам понравилось бы очень много идей... там их масса.
Например, одно из ноухау, котрых в системе не мало, вот в этом видео!
Изменено: Neufazendnik - 23.06.2018 13:01:24
 
Цитата
Neufazendnik написал:
это можно писать бесконечно.
таки-да
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете!
 
Цитата
Neufazendnik написал:
У меня есть переменная ge49, которая хранит в себе имя книги с базой данных
Напишите функцию ge49, возвращающую имя книги, и тогда текст не придется менять.
Изменено: sokol92 - 23.06.2018 14:58:21
Владимир
 
sokol92,  Это все вариации на тему решения, которое я предложил выше в посте #49.
Я предложил всесто workbooks(ge49) функцию. Вы вместо самого аргумента ge49.
Знаете тут подводный камень есть в том, что тогда нужно будет заботиться о том, чтобы workbooks(Fge49()) был доступным в уже открытом файле. Т.е доступа к файлам через getobjeсt я при таком раскладе лишусь и мне придется в этой же Fge49() в явном виде открывать файлы, ссылки на название книг которых возвращает Fge49(). Ну и далее где-то еще опять же дополнять каждый раз код закрытием этих файлов после того, как они перестали требоваться.
Изменено: Neufazendnik - 23.06.2018 15:28:40
Страницы: Пред. 1 2
Наверх