Функция/Метод XLLcmdE12xlSet(XCHAR * param, LPXLOPER12 param2, LPXLOPER12 pxReference, LPXLOPER12 pxValue) param - командная строка XLL API - см. "XLL API": 1й параметр - Режим диалога для комманд меню XLL - см. "Диалог" param2 – зарезервирован
pxReference - Прямоугольная ссылка (адрес), описывающая целевую ячейку или ячейки. Адрес должен описывать смежные ячейки.
pxValue - Значение или значения, помещаемые в ячейку или ячейки.
Аргумент pxValue pxValue может быть значением или массивом. Если это значение, этим значением заполняется весь диапазон назначения. Если это массив, элементы массива помещаются в соответствующие расположения в прямоугольнике.
Если для четвертого аргумента используется горизонтальный массив, он дублируется вниз, чтобы заполнить весь прямоугольник. Если используется вертикальный массив, он дублируется вправо для заполнения всего прямоугольника. Если вы используете прямоугольный массив, и он слишком мал для прямоугольного диапазона, в который вы хотите его поместить, этот диапазон заполняется исходными данными размером с массив, а остальной диапазон заполняется #Н/Д.
Если целевой диапазон меньше исходного массива, значения копируются до пределов целевого диапазона, а лишние данные из массива игнорируются.
Чтобы очистить элемент прямоугольника назначения, используйте элемент массива типа Empty в исходном массиве. Чтобы очистить весь прямоугольник назначения, опустите четвертый аргумент.
Ограничения Невозможно отменить xlSet . Кроме того, он удаляет все сведения об отмене, которые могли быть доступны ранее. XlSet может помещать в ячейки только константы, а не формулы. Максимальная длина помещаемой строки 8190 символов.
Возвращает код ошибки: 0 - команда выполнена успешно и Error 2036, #NUM!, #ЧИСЛО! - если ошибка.
Пример использования:
Код
Option Explicit
Sub TestXLLcmdE12xlSet()
Dim i, testSize As Long: testSize = 2
Dim arrOrValue: ReDim arrOrValue(1 To testSize, 1 To 1)
For i = 1 To testSize
arrOrValue(i, 1) = Str(i) 'MAX количество символов для ячейки: 8190
Next
'Варианты использования:
'1.Выводим массив или значение по указанному диапазону на лист Excel
Debug.Print Application.RUN("XLLcmdE12xlSet", "", 0, Range("a1:a2").Address, arrOrValue)
'2. Помещаем в диапазон значение "1"
Debug.Print Application.RUN("XLLcmdE12xlSet", "", 0, Range("b1:b2").Address, "1")
'3. Выводим массив по указанному диапазону на лист Excel, первый элемент = Empty
arrOrValue(1, 1) = Empty 'первый элемент Empty
Debug.Print Application.RUN("XLLcmdE12xlSet", "", 0, Range("c1:c2").Address, arrOrValue)
'4 Очищаем заданный диапазон от данных
[d1:d5] = 2 'заполняем данными (2) диапазон для теста
Debug.Print Application.RUN("XLLcmdE12xlSet", "", 0, Range("d1:d2").Address) ' очищаем в заданном диапазоне
End Sub
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Виталий, добрый день! По моему что-то интересное и своевременное. В то время как в соседней теме постановили, что "Эксель себя исчерпал". Это конечно все шутки. Вы как я понимаю сделали быструю выгрузку налист, как раз то чего не хватает. Не моглибы просветить темный народ, что значит тип LPXLOPER12. LP вроде понятно - указатель, а XLOPER12 это что-то вроде бейсикового Variant?
это пустой XLOPER12, в VBA не смотрел какой это тип. Надо проверить, можете потестировать, возможно Empty.
testuser, да похож на Variant, только немного попроще. Данный инструмент XLLcmdE12xlSet() по скорости обгоняет .Value2 на 15% XLOPER12 используется в Excel C API, так же как Variant в VBA. Собственно это основной тип (структура) данных. Для VBA, Excel трансформирует XLOPER12 в Variant и наоборот. В XLL я делаю это сам (ранее руками, теперь написал свой класс XloperX, даже в новостях от 7.04.24 отметил.)
bedvit написал: Собственно это основной тип (структура) данных. Для VBA, Excel трансформирует XLOPER12 в Variant и наоборот
Ну тут понятно, там где какое-нибуь трансформирование, наверняка тупое копирование, а в вашем классе это наверное релизовано как-то поумней. Такой вопрос, а нельзя ли передать в vba указатель непосредственно на массивы данных в ячеек, чтоб непосредстенно из vba можно было работать с этими данными?
bedvit: XlSet может помещать в ячейки только константы, а не формулы.
то есть, если в качестве очередного элемента массива будет "=СУММ(A1:A:5)", то так строкой и вставится? Думаю, последующее преобразование в реальную формулу не составит труда. Ну, или, тогда уж проще и быстрее использовать штатную Range().Formula = arr
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
bedvit: А может быть по другому? Работает так же, как и обычная вставка - вставляется в указанный диапазон, неважно скрыт он или нет. Штатная работает так же.
вы, молодой человек, путаете ВСТАВКУ в ячейки и ВЫГРУЗКУ массива. Твой инструмент гораздо ближе к ВЫГРУЗКЕ (практически ей и является), а у неё заполнение скрытых ячеек, как раз, не осуществляется.
И вообще — почему опять такое неуважение к конечным пользователям? Какого лешего нам опять нужно что-то додумывать и домысливать? Сложно написать "в отличие от обычной выгрузки массива на лист, НЕ игнорирует скрытые ячейки и успешно в них вставляет"???
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Что отфильтровать? При чем здесь умная таблица? Если ты про свое, то я говорю про обычную выгрузку и про копи-паст. Все они вставляют в скрытый диапазон. А про то, о чем ты говоришь - я без кода не понимаю.
bedvit: А про то, о чем ты говоришь - я без кода не понимаю.
1. отфильтруй диапазон 2. вставь в него массив размером с ВИДИМУЮ часть 3. сними фильтр 4. посмотри, вставилось ли 5. повтори всё с умной таблицей
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
bedvit, а вы не могли бы добавить опцию, чтобы передавать/получать данные непосредственно по указателю массива типа XLOPER12?? (речь о передаваче указателя как целочисленного знчения)
testuser написал: передавать/получать данные непосредственно по указателю массива типа XLOPER12??
передавать куда, и получать откуда? XLOPER12 это Си-шная структура, кто будет управлять памятью, когда я вам передам указатель на массив? Кто будет освобождать память занятую элементами массива? Каковы границы жизни указателя на массив и данных в нем (связан с первыми вопросами)?
bedvit написал: кто будет управлять памятью, когда я вам передам указатель на массив?
Вы передадите указатель мне и отпустите у себя указатель, а я разименую его на safearray-массив структуры типа XLOPER12. Попутно конечно хотелось бы знать эту структуру, на MS почему-то нет по ней информации. Да скорее всего придется в VBA коде сделать освобождение указателя на массив, но это не проблема.
testuser написал: MS почему-то нет по ней информации
Скрытый текст
Код
/*
** XL 12 Basic Datatypes
**/
typedef INT32 BOOL; /* Boolean */
typedef WCHAR XCHAR; /* Wide Character */
typedef INT32 RW; /* XL 12 Row */
typedef INT32 COL; /* XL 12 Column */
typedef DWORD_PTR IDSHEET; /* XL12 Sheet ID */
/*
** XLREF structure
**
** Describes a single rectangular reference.
*/
typedef struct xlref
{
WORD rwFirst;
WORD rwLast;
BYTE colFirst;
BYTE colLast;
} XLREF, *LPXLREF;
/*
** XLMREF structure
**
** Describes multiple rectangular references.
** This is a variable size structure, default
** size is 1 reference.
*/
typedef struct xlmref
{
WORD count;
XLREF reftbl[1]; /* actually reftbl[count] */
} XLMREF, *LPXLMREF;
/*
** XLREF12 structure
**
** Describes a single XL 12 rectangular reference.
*/
typedef struct xlref12
{
RW rwFirst;
RW rwLast;
COL colFirst;
COL colLast;
} XLREF12, *LPXLREF12;
/*
** XLMREF12 structure
**
** Describes multiple rectangular XL 12 references.
** This is a variable size structure, default
** size is 1 reference.
*/
typedef struct xlmref12
{
WORD count; //WORD
XLREF12 reftbl[1]; /* actually reftbl[count] */
} XLMREF12, *LPXLMREF12;
/*
** FP structure
**
** Describes FP structure.
*/
typedef struct _FP
{
unsigned short int rows;
unsigned short int columns;
double array[1]; /* Actually, array[rows][columns] */
} FP;
/*
** FP12 structure
**
** Describes FP structure capable of handling the big grid.
*/
typedef struct _FP12
{
INT32 rows;
INT32 columns;
double array[1]; /* Actually, array[rows][columns] */
} FP12;
/*
** XLOPER structure
**
** Excel's fundamental data type: can hold data
** of any type. Use "R" as the argument type in the
** REGISTER function.
**/
typedef struct xloper
{
union
{
double num; /* xltypeNum */
LPSTR str; /* xltypeStr */
#ifdef __cplusplus
WORD xbool; /* xltypeBool */
#else
WORD bool; /* xltypeBool */
#endif
WORD err; /* xltypeErr */
short int w; /* xltypeInt */
struct
{
WORD count; /* always = 1 */
XLREF ref;
} sref; /* xltypeSRef */
struct
{
XLMREF *lpmref;
IDSHEET idSheet;
} mref; /* xltypeRef */
struct
{
struct xloper *lparray;
WORD rows;
WORD columns;
} array; /* xltypeMulti */
struct
{
union
{
short int level; /* xlflowRestart */
short int tbctrl; /* xlflowPause */
IDSHEET idSheet; /* xlflowGoto */
} valflow;
WORD rw; /* xlflowGoto */
BYTE col; /* xlflowGoto */
BYTE xlflow;
} flow; /* xltypeFlow */
struct
{
union
{
BYTE *lpbData; /* data passed to XL */
HANDLE hdata; /* data returned from XL */
} h;
long cbData;
} bigdata; /* xltypeBigData */
} val;
WORD xltype;
} XLOPER, *LPXLOPER;
/*
** XLOPER12 structure
**
** Excel 12's fundamental data type: can hold data
** of any type. Use "U" as the argument type in the
** REGISTER function.
**/
typedef struct xloper12
{
union
{
double num; /* xltypeNum */
XCHAR *str; /* xltypeStr */
BOOL xbool; /* xltypeBool */
int err; /* xltypeErr */
int w;
struct
{
WORD count; /* always = 1 */
XLREF12 ref;
} sref; /* xltypeSRef */
struct
{
XLMREF12 *lpmref;
IDSHEET idSheet;
} mref; /* xltypeRef */
struct
{
struct xloper12 *lparray;
RW rows;
COL columns;
} array; /* xltypeMulti */
struct
{
union
{
int level; /* xlflowRestart */
int tbctrl; /* xlflowPause */
IDSHEET idSheet; /* xlflowGoto */
} valflow;
RW rw; /* xlflowGoto */
COL col; /* xlflowGoto */
BYTE xlflow;
} flow; /* xltypeFlow */
struct
{
union
{
BYTE *lpbData; /* data passed to XL */
HANDLE hdata; /* data returned from XL */
} h;
long cbData;
} bigdata; /* xltypeBigData */
} val;
DWORD xltype;
} XLOPER12, *LPXLOPER12;
/*
** XLOPER and XLOPER12 data types
**
** Used for xltype field of XLOPER and XLOPER12 structures
*/
#define xltypeNum 0x0001
#define xltypeStr 0x0002
#define xltypeBool 0x0004
#define xltypeRef 0x0008
#define xltypeErr 0x0010
#define xltypeFlow 0x0020
#define xltypeMulti 0x0040
#define xltypeMissing 0x0080
#define xltypeNil 0x0100
#define xltypeSRef 0x0400
#define xltypeInt 0x0800
#define xlbitXLFree 0x1000
#define xlbitDLLFree 0x4000
#define xltypeBigData (xltypeStr | xltypeInt)
/*
** Error codes
**
** Used for val.err field of XLOPER and XLOPER12 structures
** when constructing error XLOPERs and XLOPER12s
*/
#define xlerrNull 0
#define xlerrDiv0 7
#define xlerrValue 15
#define xlerrRef 23
#define xlerrName 29
#define xlerrNum 36
#define xlerrNA 42
#define xlerrGettingData 43
Цитата
testuser написал: освобождение указателя на массив, но это не проблема.
уверен, что вы не до конца понимаете с чем столкнетесь. Зачем вам это? Как вы с этими данными будете работать? Не будет там никакого safearrey, это СОМ, не путайте.
bedvit, можно сделать просто в vba получить указатель разименовать, поработать с данными, и отпустить указатель, как буд-то ни чего не был, а менеджер памти Excel пусть делает что хочет. В общем на VBa все это не проблемма, главное знать структуру данных. Структура конечно не очен понятна, со всеми этими юнитами, нельзя ли ее привести к какому-то такому виду?
Код
Private Type tpVariant
vt As Integer
r1 As Integer
r2 As Integer
r3 As Integer
pt As LongPtr
r4 As LongPtr
End Type
testuser написал: в vba получить указатель разименовать, поработать с данными, и отпустить указатель, как буд-то ни чего не был, а менеджер памти Excel пусть делает что хочет. В общем на VBa все это не проблемма
Теперь все прояснилось, благодарю.
Цитата
testuser написал: нельзя ли ее привести к какому-то такому виду?
Уверен, что после указателей, вам не составит труда справится и с этой проблемой!