Създаване на обобщаваща таблица с едномерен динамичен масив, тип User Data Type

Безплатни 20 урока
регистрирай се и научи

Ако сте вече потребител - Регистриран съм
Видео

Тест за преминаване към следващия урок

 
Оператор Redim променя размера на динамичния масив. За да се запазят въведените елементи в динамичния масив при повторно задаване на Redim, използваме оператор:
Preserve
Static
Option Base 1
 
Каква е разликата между променлива и масив?
Променливата съхранява единична стойност, а масивът - повече стойности
Променливата съхранява единична стойност от един тип, а масивът само числа
Няма разлика

Въпроси и отговори

  • Защо total_sales = total_sales +....?

    Cvetelina Raykova:

    Още от началот на курса се чудя защо total_sales = total_sales + Range("B" & m).Value? Не мога да разбера защо не е total_sales = Range("B" & m).Value, та дефинирането на total_commis става тук, т.е. ако total_sales = total_sales, то това не е нищо. Незнам дали разбирате какво искам да питам, но пробвах total_sales = Range("B" & m).Value и тогава не сумира стойностите на целия рейндж, а запазва само последната.

    Дарина Иванова:

    Знак "=" се тълкува като оператор за присвояване, а не като знак за равенство. Смисълът на присвояването тук може да опишем в следните стъпки: 1. На променливата total_sales=0 (дава се начална стойност на променливата 0, за да сме сигурни, че натрупването на сумата започва на чисто. 2. Към старата стойност на променливата добави стойността на определена зона и я превърни в нова стойност на същата променлива. (total_sales(ново)=total_sales(старо)+Range("B"&m).Value

    Cvetelina Raykova:

    Благодаря за отговора.

  • Защо сумира total_sales и total_commis с натрупване от първия към последния лист?

    Cvetelina Raykova:

    За упражнение повтарям процедурите в този урок, но имам проблем. В сумарните редове total_sales и total_commis събира стойностите с натрупване от първия към последния лист. Проверих си процедурата с вашата и не виждам разлика, а резултатът е различен.

    Option Explicit Type Table_title ime As String sales As Currency commis As Currency End Type

    Const Perc1 = 0.15, Perc2 = 0.25

    Dim sht As Worksheet Dim total_sales As Long, total_commis As Long Dim total_wsales As Long, total_wcommis As Long Dim last_row As Long Dim sht_nu As Integer, m%, l%, n% Dim array_week() As Week_data Dim array_title

    Public Sub Consolidate_data()

    sht_nu = ActiveWorkbook.Worksheets.Count

    For Each sht In ActiveWorkbook.Worksheets sht.Select last_row = Range("A1").End(xlDown).Row

    For m = 2 To last_row

    If Range("B" & m) >= 3500 Then Range("C" & m) = Perc2 If Range("B" & m) < 3500 Then Range("C" & m) = Perc1

    Range("C" & m).NumberFormat = "0%" Range("D" & m) = Range("B" & m).Range("C" & m) Range("D" & m).NumberFormat = "0$"

    Range("D" & m) = Range("B" & m) * Range("C" & m) total_sales = total_sales + Range("B" & m).Value total_commis = total_commis + Range("D" & m).Value

    Next m

    Range("A" & last_row + 1) = "Общо" Range("B" & last_row + 1) = total_sales Range("D" & last_row + 1) = total_commis

    Next sht

    Cvetelina Raykova:

    Сега забелязах, че и вашата продедура "Fill_Table" работи по същия начин.

    Cvetelina Raykova:

    total_sales и total_commis натрупват стойностите, защото в процедурата определяме че total_sales = total_sales +......., но след първия лист total_sales пази стойностите и за предходния. Не знам как да дефинирам, че total_sales = само на total_sales от активния лист.

    Димитринка Вълкова:

    Здравей Цветелина. В урока обръщам специално внимание, че в процедурата има една "особеност". Това е една "уловка" и предизвикателство да се намери причината за некоректното натрупване на сумите. Много добре си се справила с това предизвикателство, точно така стойностите на двете променливи total_sales и total_commmis трябва да натрупват сумите само за активния лист. За следващия лист двете променливи трябва да се нулират, за да започне отново натрупването. Дарина много подробно е отговорила на предишния ти въпрос как променливите съхраняват стойности. За да се нулират или "изчистят" променливите, се присвоява 0. И така, за да сумира само за активния лист, може да добавиш в началото на блок-оператор For each sht, в процедурата Fill_Table следните инструкции: total_sales=0 total_commis=0

    Cvetelina Raykova:

    Благодаря Ви за отговора.

  • Как да разбирам обект дефиниран с: Range("B2:C" & sht_nu +2).

    Иван Тихов:

    Какъв обект е дефиниран с: Range("B2:C" & sht_nu +2). Моля да обясните подробно

    Димитринка Вълкова:

    Обект Range може да се дефинира по различни начини. Например: Range("B2:C4") - това е абсолютна референция за обекта и при всяко изпълнение на процедурата ще посочва този обект. Но вместо номера на реда може да се използва променлива ( в примера променливата е sht_nu, на която предварително се присвоява стойност, да кажем sh_nu=5). Следователно обект Range("B2:C"& sht_nu + 2) определя референцията "B2:C7". Когато в процедурите дефинираме обект, е много по-удобно, по-гъвкаво да се използват променливи. Припомни си примерите от предишния модул 4, урок 9, Sub Array_Sales, module Step6. Надявам се, че бях полезна с отговора, но ако все още не е ясно пиши.

  • Може ли да се зададе така процедурата, че да не се изпълнява във всеки Sheet?

    Христиана Георгиева:

    Може ли да се зададе така процедурата, че да не се изпълнява във всеки Sheet. Тоест, ако имаме други листове с данни, които не са съвместими, те да не участват?

    Димитринка Вълкова:

    Достатъчно е в процедурата да се зададе условие за кои листове да се изпълнява. Например, ако процедурата трябва да се изпълнява само за листове, чието име започва с "Primer*", условието може да се запише така: If sht.Name Like "Primer" Then ... и следва програмен код. Обърнете внимание, sht е декларираната променлива-обект Worksheet. Ако дадете конкретен пример при какво условие да се изпълнява процедурата, ще се опитам да помогна

  • Защо Range(cells(1,3),cells(Ubound(Arr)+1,3)) се променя така?

    Надежда Попниколова:

    Когато попълвам масива с оператор For i = 1 to last_row..., след това при копирането в колона С, започва да го попълва от клетка С2. Въпреки че за начало на Range е зададено cells(1,3).

    Знам, че ако попълня масива с оператор For i = 0 to last_row..., след това се попълва коректно от клетка С1:

    !

    Само че ми убягва логическото обяснение за това. Може ли да ми разясните защо става така? Благодаря предварително!

    Димитринка Вълкова:

    По подразбиране, първият елемент на масива има индекс 0, това е стойността на LBound. Когато определяте i = 1, попълването започва от втория елемент, който има индекс 1. Елементите на масива се попълват със стойностите, но индексите са отместени с 1 - първият елемент на масива Arr(0) е празен и се записва в С1, вторият елемент Arr(1) се записва в С2. Масивът има 23 елемента, защото UBound = last_row = 22. Когато определяте i=0, тогава диапазонът включва един празен ред, това е последният елемент Arr(22), но масивът също има 23 елемента. Объркването идва от първия елемент на масива, който има индекс 0. За да видите сама как се записват данните от масива, добавете инструкция rng.Select, след дефинирането на rng (Set rng = ...) Надявам се, че отговорих на въпроса. Разбира се, ако имате още въпроси, пишете.

    Надежда Попниколова:

    Сега вече ми се разясни. Благодаря за отговора!