Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.53/15: Рейтинг темы: голосов - 15, средняя оценка - 4.53
1 / 1 / 2
Регистрация: 08.12.2015
Сообщений: 24
1

Копирование/вставка выделенного диапазона ячеек StringGrid (XE2)

22.01.2016, 22:00. Показов 2865. Ответов 2
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте! Вот такой вопрос возник: как в таблице StringGrid при выделении диапазона ячеек скопировать их содержимое и потом вставить в пределах этой же таблицы? Как при работе с таблицами в Word или Excel. Это нужно для удобства редактирования исходных данных.

Не покидает ощущение, что для этого должна существовать встроенная функция. Но какая именно? Не нашёл.

Кто сталкивался? Как это реализовать?

Заранее спасибо.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.01.2016, 22:00
Ответы с готовыми решениями:

Закраска заданного диапазона ячеек StringGrid
Добрый день ребята Мне нужно закрасить область ячеек число которых будут прочитаны из этого...

Копирование ячеек в StringGrid
написал такой вот цикл, обрабатывает только первую строчку и все. :( for (i = 1; i < 4 ; i++)...

Копирование выделенного диапазона ячеек, только значения
Всем привет. Помогите пожалуйста, дописать код: Sub CopySelectedRangeToNewSheet() Dim...

Вставка текста вокруг выделенного диапазона
Добрый день! Помогите, пожалуйста, с кодом для кнопки, при нажатии на которую вставляется...

2
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32835 / 21172 / 8148
Регистрация: 22.10.2011
Сообщений: 36,431
Записей в блоге: 8
22.01.2016, 22:49 2
Цитата Сообщение от Enzi Посмотреть сообщение
для этого должна существовать встроенная функция
Нет, такой функции не существует. Вручную: внешний цикл по строкам от grid->Selection.Top до grid->Selection.Bottom, и внутренний - по ячейкам - от grid->Selection.Left до grid->Selection.Right, сохраняем размеры Selection и значения ячеек в какой-то контейнер, и потом перезаписываем в другую область грида
0
1 / 1 / 2
Регистрация: 08.12.2015
Сообщений: 24
26.01.2016, 21:16  [ТС] 3
Лучший ответ Сообщение было отмечено Enzi как решение

Решение

volvo, да тут не всё так просто оказалось...

В общем, проблема решена. Оставляю материалы. Дремучим потомкам в назидание.

Для начала, в билдере в редактируемой вручную таблице нет возможности выделять диапазон ячеек. В Options таблицы goRangeSelect и goEditing одновременно не работают.

Решение этой проблемы нашёл на просторах сети. Что и как там работает - понятия не имею. Но работает же!

В .h файле нужно прописать
C++
1
2
3
4
public:
    //Нужно для мультивыделения ячеек
    void __fastcall hooku(tagMSG& fr,bool& re);
}
Потом в .cpp файле в классе формы нужно добавить описание
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void __fastcall TDataInput::hooku(tagMSG& fr,bool& re)
{
tagPOINT tp;
int Col1,Row1;
if (fr.hwnd==StringGrid1->Handle)
{
if (fr.message==WM_LBUTTONDOWN)
{
tp=StringGrid1->ScreenToClient(fr.pt);
StringGrid1->MouseToCell(tp.x,tp.y,Col1,Row1);
if (!((Col1==StringGrid1->Col)&&(Row1==StringGrid1->Row)))
{
StringGrid1->Options >> goEditing;
StringGrid1->Options << goRangeSelect;
};
};
if (fr.message==WM_LBUTTONUP)
{
StringGrid1->Options << goEditing;
StringGrid1->Options >> goRangeSelect;
};
};
};
Затем нужно создать форме (у меня она называется DataInput) обработчик события OnCreate со следующим текстом:
C++
1
2
3
4
5
void __fastcall TDataInput::FormCreate(TObject *Sender)
{
    //Нужно для мультивыделения ячеек
    Application->OnMessage=hooku;
}
Проблема решена. теперь в таблице можно выделять диапазон ячеек. Хочешь - мышью, не хочешь - шифтом. При этом сохраняется возможность редактирования содержимого ячеек по двойному нажатию мыши.

Идём дальше. Создаём таблицу-контейнер. У меня в примере она называется MC - таблица класса StringGrid, изначально невидимая (Visible=False). Теперь, собственно, нужно создать для основной таблицы (где будет реализовано копирование/вставка) обработчик события OnKeyDown со следующим кодом:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
void __fastcall TDataInput::StringGrid1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
int c,r;
int mc,mr;
int mci,mri;
int ac,ar;
 
    //Код для команды "Скопировать"
if ((Key == 'C')&& Shift.Contains(ssCtrl))
      {
      MC->Tag=1;
 
      mc=StringGrid1->Selection.Right-StringGrid1->Selection.Left+1;
      mr=StringGrid1->Selection.Bottom-StringGrid1->Selection.Top+1;
 
      MC->ColCount=mc;
      MC->RowCount=mr;
 
      mci=-1;
      mri=-1;
 
 
       for(c=StringGrid1->Selection.Left;c<=StringGrid1->Selection.Right;c++)
       {
 
            mci++;
 
            for(r=StringGrid1->Selection.Top;r<=StringGrid1->Selection.Bottom;r++)
            {
                mri++;
 
                MC->Cells[mci][mri]=StringGrid1->Cells[c][r];
            }
            mri=-1;
 
       }
 
      }
 
//Код для команды "Вырезать"
if ((Key == 'X')&& Shift.Contains(ssCtrl))
      {
      MC->Tag=2;
 
      mc=StringGrid1->Selection.Right-StringGrid1->Selection.Left+1;
      mr=StringGrid1->Selection.Bottom-StringGrid1->Selection.Top+1;
 
      MC->ColCount=mc;
      MC->RowCount=mr;
 
      mci=-1;
      mri=-1;
 
 
       for(c=StringGrid1->Selection.Left;c<=StringGrid1->Selection.Right;c++)
       {
 
            mci++;
 
            for(r=StringGrid1->Selection.Top;r<=StringGrid1->Selection.Bottom;r++)
            {
                mri++;
 
                MC->Cells[mci][mri]=StringGrid1->Cells[c][r];
                StringGrid1->Cells[c][r]="";
            }
            mri=-1;
 
       }
 
      }
 
      //Код для команды "Вставить"
if ((Key == 'V')&& Shift.Contains(ssCtrl))
      {
 
      if(MC->Tag==1 || MC->Tag==2)
      {
          if(MC->Tag==2) MC->Tag=0;
 
          ac=StringGrid1->Selection.Left;
          ar=StringGrid1->Selection.Top;
 
          mci=ac-1;
          mri=ar-1;
 
 
           for(c=0;c<MC->ColCount;c++)
           {
 
                mci++;
 
                for(r=0;r<MC->RowCount;r++)
                {
                    mri++;
 
                    StringGrid1->Cells[mci][mri]=MC->Cells[c][r];
                }
                mri=ar-1;
           }
      }
 
      }
 
//Код для команды "Удалить"
if (Key == VK_DELETE)
    {
        for(c=StringGrid1->Selection.Left;c<=StringGrid1->Selection.Right;c++)
        {
 
            for(r=StringGrid1->Selection.Top;r<=StringGrid1->Selection.Bottom;r++)
            {
                StringGrid1->Cells[c][r]="";
            }
        }
 
    }
}
Теперь в пределах основной таблицы можно копировать/вырезать/вставлять содержимое выделенного диапазона ячеек. Я также добавил сюда возможность удалять содержимое диапазона по нажатию клавиши Delete, это функции по-умолчанию тоже нет.

Кому надо, пользуйтесь на здоровье!
1
26.01.2016, 21:16
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.01.2016, 21:16
Помогаю со студенческими работами здесь

Нарисовать внешние границы выделенного диапазона ячеек в EXCEL
Товарищи подскажите как выделить только внешние границы у выделенного диапазона ячеек в excel ? ...

Макрос для подсчета среднего геометрического выделенного диапазона ячеек
Здравствуйте!буду очень признательна если поможете в написании макроса,нужен для расчетов в...

Как в гугл- таблицах сделать автоматическое копирование выделенного диапазона при конкретном значении ячейки
Доброго времени суток! Столкнулась с необходимостью создания таблицы для мини-учёта товарных...

Копирование диапазона ячеек
Уважаемые форумчане, подскажите, пожалуйста. Хочу скопировать диапазон ячеек с одного листа на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru