23.04.2004, 15:54 | #1 |
Участник
|
Класс двумерного массива
Есть ли в Axapta 2.5 класс двумерного массива?
Цель - подготовка массива перед выводом в Excel через буфер обмена. Нужно иметь возможность динамически вставлять (удалять) строки и столбцы. Собственно, не проблема сделать этот класс самому как массив массивов, что-то вроде: PHP код:
|
|
23.04.2004, 18:26 | #2 |
Участник
|
А контейнеры не устраивают? Там с удалением/добавлением вроде все ОК...
|
|
26.04.2004, 13:36 | #3 |
Участник
|
Мне требуется вставлять/удалять целые строки и столбцы. Через контейнер это реализовать проблематично.
Впрочем, класс я уже сделал. Использую MAP для хранения значений, а индексы массива записаны в 2 контейнера. Порядковый номер элемента в контейнере - это значение индекса в массиве, а значение элемента в контейнере - это значение ключа MAP по которому следует искать значение элемента массива. Т.е. вставка/удаление - это вставка/удаление индексов, сами элементы при этом остаются там же, где и были. |
|
26.04.2004, 13:58 | #4 |
Участник
|
Если не сложно, скинь пожалуйста сюда класс. Думаю возможно в скором будущем тоже понадобится.
|
|
26.04.2004, 15:39 | #5 |
Участник
|
Двумерный массив легко организовывается через одномерный, то есть работа идет на деле с одномерным, а при кодировании имитируются двумерные. Вот соотв. фрагмент из Language reference :
Multiple array indices From other languages like C++ and java, you may be used to declaring arrays with more than one index, that is to define "arrays of arrays". This is not possible directly in X++. Only one-dimensional arrays are supported. However, it is easy to implement multiple indices by using the scheme described below. Say you wanted to declare an array with two dimensions, for holding an amount earned by country by dimension. What you want to declare is real earning[10, 3]; where there are 10 countries and 3 dimensions. This is not possible in Axapta, but you can circumvent the problem by defining an one dimensional array with the number of elements that is the product of the elements in each dimension: real earnings[10*3]; When you wish to refer to earnings[i,j], you simply write earnings[(i-1)*3 +j]. You can easily wrap this into a macro: #localmacro.earningIndex (%1-1)*3+%2 #endmacro so you could write earnings[#earningIndex(i,j)] The above scheme may easily be extended to any number of dimensions. The element a[i1, i2, ..., ik] can be accesses by computing the offset (i1 - 1)*d2*d3*..*dk + (i2 - 1)*d3*d4*...*dk + .... + (ik-1 -1)*dk + (ik-1) into an array containing (d1*d2*...*dk) elements |
|
26.04.2004, 15:50 | #6 |
Участник
|
NeveB
Класс прилагаю, описание в методе Description Zabr Прикиньте, пожалуйста, какие понадобяться действия, чтобы вставить или удалить строку или столбец в массив, организованный по описанной Вами схеме. Если со строками, все относительно просто, то вот со столбцами - куча проблем. Есть и другие недостатки такой схемы. |
|
26.04.2004, 16:01 | #7 |
Administrator
|
Цитата:
Изначально опубликовано Владимир Максимов
[Прикиньте, пожалуйста, какие понадобяться действия, чтобы вставить или удалить строку или столбец в массив, организованный по описанной Вами схеме...
__________________
Not registered yet? Register here! Have comments, questions, suggestions or anything else regarding our web site? Don't hesitate, send them to me |
|
26.04.2004, 16:08 | #8 |
Участник
|
Цитата:
Так на то это и массив, а не список. Массивы никогда не предполагают легкой жизни при удалении элементов.
Да и списки бывают разные |
|
27.04.2004, 07:02 | #9 |
Участник
|
За класс премного благодарен
|
|
27.04.2004, 09:21 | #10 |
Участник
|
с вашего позволения перенесу я эту ветку в проекты.
спасибо за класс. |
|
27.04.2004, 18:18 | #11 |
Участник
|
Переделал класс для работы с любым типом данных допустимом в контейнере. Т.е. в массиве можно одновременно хранить данные разных типов!
Ну, и заодно, пригладил код в соответсвии с рекомендациями Best Practise Правда, у меня не получилось сделать универсальный код для вообще любого типа данных Т.е. создать MAP(types::container,types::anyType) - не проблема. И даже записать в него данные получилось. Но вот вытащить из него данные - уже никак Не читает их и все! Поэтому пришлось сделать хранение через контейнер, что ограничило использование типов данных только теми, которые допустимы внутри контейнера. Впрочем, и это не мало |
|
27.04.2004, 18:58 | #12 |
Участник
|
хм... начинаю сомневаться в целесообразности усилий.
Тогда ответьте, пожалуйста, на вопрос: почему не взяли за основу класс array из Axapta Foundation Calsses? См. http://www.axforum.info/forums/showt...1254#post11254 PHP код:
Ребяты! Давате жить... без программирования там, где не нужно программировать. |
|
27.04.2004, 19:02 | #13 |
Участник
|
и еще вопросы.
= вы будете заниматься сериализацией вашего массива? = как вы планируете передавать ваш массив между клиентом и сервером в трехуровневой конфигурации? и напоследок вернемся к исходному вопросу - почему вцы решили создавать свой класс, а не наследовать от существующего array? |
|
28.04.2004, 10:34 | #14 |
Участник
|
Постановка задачи, из-за которой я собственно создал этот класс ставилась так:
1) Создать массив, в котором можно в любой момент вставить столбец в указанное место. 2) Массив является неким образом сетки Excel, для последующего экспорта в Excel через буфер обмена 1) Создать массив, в котором можно в любой момент вставить столбец в указанное место. Т.е. на этапе формирования отчета я заранее не знаю ни сколько столбцов будет вообще, ни где именно они будут располагаться (порядок следования). Это выясняется в процессе сканирования результирующей выборки (query). Делать предварительную выборку для определения количества и порядка следования столбцов нерационально, поскольку время выполнения такого запроса сопоставимо с временем выполнения основной выборки. Если не разделять адресацию и содержимое массива (массив массивов, синтетическая адресация в одномерном массиве и т.п.), то возникают проблемы при вставке нового столбца. Потребуется фактически скопировать содержимое ранее созданного массива в новый массив с вставкой пустых элементов как нового столбца. Я посчитал, что это будет относительно длительная по времени операция. Поэтому я разделил адреса и содержимое массива и при вставке нового столбца меняю только адресацию НЕ ИЗМЕНЯЯ содержимого. Реализовать это без введения дополнительных объектов - невозможно. Отсюда класс для хранения как собственно содержимого массива, так и их адресов, плюс методы по их обработке. 2) Массив является неким образом сетки Excel, для последующего экспорта в Excel через буфер обмена Метод toString имеет целью прежде всего сформировать символьную строку, которую я затем впихиваю в буфер обмена (отсюда num2chr(9) и num2char(13)). Более того, метод конвертации в строку anyValue2str использует конвертацию через strFmt() именно для того, чтобы конвертация произошла в формате настроек системы, которые и используются в Excel. Т.е. в этом случае, например, в качестве разделителя целой и дробной части числа будет использован тот символ, который и используется в Excel и не возникнет ошибки "запись числа как текста" Т.е. по окончании формирования массива следует что-то вроде: textBuffer.setText(rtg_2DimArray.toStrin()); И вставка этого буфера в указанную ячейку Excel, через Ваш метод InsertText() Включение возможности хранить различные типы данных сделано для возможности выполнения расчета итогов по строкам. Т.е. крайний правый столбец должен содержать сумму по всем ячейкам данной строки. Да и появляется возможность расчета промежуточных итогов по столбцам. Но вообще-то, возможность хранения разнотипных данных позволяет сформировать ВЕСЬ лист Excel в одном объекте не вводя дополнительные сущности. Цитата:
= вы будете заниматься сериализацией вашего массива?
= как вы планируете передавать ваш массив между клиентом и сервером в трехуровневой конфигурации? Передача между клиентом и сервером вообще не планируется (если я правильно понял о чем речь). Цель данного массива - это формирование символьной строки для передачи данных в Excel через буфер обмена. |
|
28.04.2004, 12:32 | #15 |
Участник
|
Совершенно не провти такой постановки.
Просто я думал, что это учебный проект. Для учебного проекта нормально - когда идет создание с нуля, когда тратится куча времени. А это оказывается часть коммерческой разработки. Для коммерческой разработки ИМХО странно когда тратится куча времени. Поэтому то я и спросил - почему вы СОЗДАЕТЕ, а не НАСЛЕДУЕТЕ? ведь если бы вы унаследовали от системного класса array, то вам пришлось бы делать маленьку часть - пересчитать двумерные индексы в одномерный по простейшему арифметическому алгоритму.... Цитата:
Изначально опубликовано Владимир Максимов
Постановка задачи, из-за которой я собственно создал этот класс ставилась так: 1) Создать массив... Вам виднее. Цитата:
Изначально опубликовано Владимир Максимов
Честно говоря, я не понял этих вопросов. Что подразумевается под термином "сериализация"? На механизме сериализации в сатнадртной Аксапте держится передача данных между клиентом и сервером в трехуровневой среде. Цитата:
Изначально опубликовано Владимир Максимов
Передача между клиентом и сервером вообще не планируется (если я правильно понял о чем речь). Цель данного массива - это формирование символьной строки для передачи данных в Excel через буфер обмена. По прежнему не понимаю, почему вы СОЗДАЕТЕ, а не НАСЛЕДУЕТЕ. Но вам виднее. |
|
28.04.2004, 15:14 | #16 |
Участник
|
Не понимаю. У меня ощущение, что Вы пропускаете принципиально важный момент моей задачи:
Необходимо иметь возможность вставить столбец между раннее созданными столбцами. Т.е. сначала были созданы столбцы 1,2,3, а постом возникла необходимость вставить еще один столбец перед 2. Как это можно реализовать через стандартный функционал Axapta 2.5? |
|
28.04.2004, 16:28 | #17 |
Участник
|
Цитата:
Изначально опубликовано Владимир Максимов
Необходимо иметь возможность вставить столбец между раннее созданными столбцами. Как это можно реализовать через стандартный функционал Axapta 2.5? При желаниии можно работать с одномерным массивом как с двумерным, используя пересчет. Но это не столь удобно и производительно. Если бы в аксапте были реализованы многомерные (или хотя бы двумерные) массивы, то вообще бы не пришлось вставлять данные в Excel через буфер обмена. Можно было просто передать в нужный range двумерный вариантный массив.. p.s. Если честно ,я не совсем понимаю зачем нужно иметь возможность менять местами и строки, и столбцы. Задача похоже несколько надуманная... |
|
28.04.2004, 17:13 | #18 |
Участник
|
Цитата:
Изначально опубликовано Владимир Максимов Необходимо иметь возможность вставить столбец между раннее созданными столбцами.
С ума сойти, кто ж писал такое техзадание? Кто выделил деньги на такие работы? Интересно, как будет приниматься работа? Даю маячок: То, что вы создали (Цитата: "Общий принцип: адреса элементов и содержимое элементов храняться отдельно") массивом не является. А в вашем техзадании первые два слова "Создать массив" |
|
28.04.2004, 17:15 | #19 |
Участник
|
Цитата:
Изначально опубликовано dn
Можно было просто передать в нужный range двумерный вариантный массив... Чем в момент передачи двумерный массив отличается от одномерного? |
|
28.04.2004, 17:20 | #20 |
Участник
|
И ни смотря ни на что...
Владимир Максимов, спасибо за выполненный и опубликованный проект. |
|