Պլան ցանկացած կտրվածքով — առանց հաշվետվությունը վերակառուցելու
Վաճառքի պլանավորում DAX-ով — պլան, որ վերահավաքվում է րոպեներում
Մենեջերը բացում է մեկ թերթ և շրջում ֆիլտրերը։ Պլանն ու փաստը համեմատելի են ցանկացած կտրվածքով՝ ղեկավարից մինչ հաճախորդ և օր։ Իսկ պլանի վերանայումը Google Sheets-ում խմբագրում է, ոչ թե հաշվետվության վերակառուցում։
Պլանը մուտքագրվում է Google Sheets-ում երկու ռեժիմով, նորմալացվում Power Query-ում և բաշխվում երեք բաշխմամբ՝ ամիս→օր, բրենդ→SKU, ներկ.→հաճախորդ։ Հետո՝ աստղ-սխեմա Power Pivot-ում և պլան/փաստ չափիչներ DAX-ով։
01Ինչպես էր աշխատում մինչ մեզ
Ընկերությունը հաճախ էր վերանայում վաճառքի պլանը՝ փոխելով բրենդի թիրախները, տեղափոխելով ծանրաբեռնվածությունը ներկայացուցիչների միջև, վերանշանակելով ալիքների պատասխանատուներ։ Ամեն այդպիսի վերանայում բախվում էր նույն պատին։
- «Պլան vs փաստ»-ն ըստ բրենդի՝ ալիքում համադրելու համար ինչ-որ մեկը հավաքում էր տվյալները տարբեր արտահանումներից ձեռքով ամեն շաբաթ։ Դանդաղ և սխալների ենթակա։
- Ղեկավարության նոր հարցը («ցույց տուր ըստ ղեկավարի՝ եռամսյակով», «որքա՞ն պլան է կախված այս հաճախորդից») նշանակում էր նորից փորփրել աղյուսակները՝ պատրաստի կտրվածք չկար։
- Պլանը մի ներկայացուցչից մյուսին վերանշանակելը նշանակում էր պատմությունը վերագրել մի քանի ֆայլում՝ առանց ինչ-որ բան կոտրելու։ Պրակտիկայում հենց այնտեղ էր կոտրվում։
Այս ընկերությունում պլանը կենդանի փաստաթուղթ է. ղեկավարությունը վերանայում է այն ողջ տարվա ընթացքում, տեղափոխում թիրախները ներկայացուցիչների և բրենդերի միջև, փոխում պատասխանատուներ։ Մինչ նախագիծը՝ պլանավորումն ապրում էր ցրված աղյուսակների հավաքածուում, որ հավաքվում էր ձեռքով ամեն շաբաթ։
- Պլանի վերանայում = ամեն ինչ վերակառուցել։ Ամեն փոփոխություն նշանակում էր թիրախները ձեռքով վերաբաշխել ըստ բաժինների և բրենդերի՝ ժամանակի հսկայական ծախս։
- Ռելյացիոն կապեր չկան՝ rollup չկա։ Պլանի և փաստի աղյուսակները կապված չէին։ «Պլան vs փաստ ըստ բրենդի՝ ալիքում»-ը հավաքվում էր ձեռքով՝ շաբաթական։
- Վիզուալիզացիան թույլ էր։ Առանց տվյալների մոդելի ցանկացած ամփոփում մեկ հարցի ստատիկ թերթ է։ Նոր կտրվածքը նշանակում էր նորից փորփրել արտահանումները։
- Պատասխանատու վերանշանակելը՝ աղետ։ Պատմությունը մի քանի աղյուսակում վերագրել առանց ինչ-որ բան կոտրելու՝ սխալների և կորած ժամանակի աղբյուր։
- Պլանավորման տարբեր խորություն։ Որոշ բրենդեր պլանավորվում էին մանրամասն՝ ըստ ապրանքի, մյուսները՝ ընդհանուր գծերով ըստ բրենդի և ալիքի։ Երկու մոտեցումը մեկ՝ փաստի հետ համեմատելի պատկերի ձեռքով համադրելը գրեթե անհնար է։
02Ինչ կառուցեցինք
Գլխավոր էկրան՝ պլան և փաստ ըստ մարդկանց
Մենեջերը բացում է մեկ թերթ և շրջում ֆիլտրերը։ Պլանն ու փաստը միշտ համեմատելի են՝ որովհետև հաշվվում են մեկ մոդելից և ֆիլտրվում նույն կապերով։ «% կատարման» սյունակի գույնը մեկ հայացքով ցույց է տալիս, թե ով է հետ մնում։
| Ներկայացուցիչ | Ղեկավար | Պլան, ֏ | Փաստ, ֏ | % կատարման | Պլան, հատ | Փաստ, հատ |
|---|
* Ներկայացուցչի և ղեկավարի անունները տեղապահեր են։ Սանդղակ՝ ≥100% · 85–99% · <85%։
Հոսքը ծանոթ է՝ ընտրեք եռամսյակ՝ տեսեք, ով է հետ մնում, ընտրեք ղեկավար՝ նրա թիմի պատկերը, ավելացրեք բրենդ կամ ալիք՝ նեղացրեք ուղղության։ Եվ հաշվետվությունը չի վերակառուցվում՝ մեկ էկրանը փակում է տասնյակ հարցեր։
Պլանի բաշխում հաճախորդին
Պլանը դրվում է ներկայացուցչի և բրենդի վրա՝ պլանում հաճախորդ չկա։ Բայց մենեջերը հաճախ պետք է հասկանա, թե որ հաճախորդներից է «կախված» տվյալ ներկայացուցչի պլանը։ Մոդելը ներկայացուցչի պլանը բաշխում է նրա հաճախորդներին ամեն հաճախորդի փաստացի վաճառքի մասնաբաժնի համամասնությամբ՝ ընտրեք ներկայացուցիչ և տեսեք, ինչպես է բաշխվում նրա թիրախը։
Ներկայացուցչի պլանն եռամսյակում՝ · բաշխված հաճախորդներին՝ ըստ նրանց փաստացի վաճառքի մասնաբաժնի։
| Հաճախորդ | Փաստ վաճառք, ֏ | Մասնաբաժին | Բաշխված պլան, ֏ | % կատարման |
|---|
* Հաճախորդների անունները թաքնված են։ Նույն մեթոդը պլանը բաշխում է ցանկացած կտրվածքի, որտեղ փաստացի վաճառք կա։
Պլանի վերանայում — խմբագրում Google Sheets-ում
Ղեկավարությունը պլանը պահում է ոչ հաշվետվությունում և ոչ ERP-ում, այլ Google Sheets-ում՝ այն տեսքով, որով հարմար է պլանավորել։ Որոշ բրենդեր պլանավորվում են մանրամասն ըստ ապրանքի, մյուսները՝ ընդհանուր գծերով ըստ բրենդի և ալիքի։ Երկուսն էլ ապրում են մեկ ֆայլում տարբեր թերթերում։
| Բրենդ | Ալիք | Ներկ. | Ամիս | Պլան, ֏ |
|---|---|---|---|---|
| [Բրենդ 1] | Դեղատների ցանցեր | [Ներկ. A] | Ապր 2026 | 8 720 000 |
| [Բրենդ 1] | Բաշխիչներ | [Ներկ. A] | Ապր 2026 | 5 810 000 |
| [Բրենդ 2] | Marketplace-ներ | [Ներկ. B] | Ապր 2026 | 4 340 000 |
| [Բրենդ 3] | Դեղատների ցանցեր | [Ներկ. C] | Ապր 2026 | 6 770 000 |
Այնտեղից մոդելն անում է մնացածը՝ ամսական պլանը բաշխում է օրերի, ամփոփ թիրախը բաշխում կոնկրետ ապրանքների՝ ըստ վաճառքի մասնաբաժնի, կապում օրացույցին և վերահաշվում «% կատարման»-ը։ Ղեկավարությունից՝ միայն թվերն աղյուսակում։
Ինչպես է թարմացվում տվյալը
QuickBooks-ից փաստերի պատրաստումը սովորական ֆայլ-արտահանում է՝ ոչ ծրագրավորող, ոչ կարգաբերում։ Մնացած ամեն ինչը մոդելի կողմում է։ Մեկ սեղմումը քաշում է թե՛ թարմ պլանը Google Sheets-ից, թե՛ թարմ փաստը արտահանումից։
Ինչ դարձավ հնարավոր
- Մեկ էկրան՝ տասնյակ հարցերի։ Ղեկ., ներկ., բրենդ, ալիք, եռամսյակ՝ ցանկացած կտրվածք առանց հաշվետվությունը վերակառուցելու։
- Պլանը հայտնվում է այնտեղ, որտեղ այն երբեք չի դրվել։ Հաճախորդին և ապրանքին բաշխումը ցույց է տալիս պլանը կտրվածքներում, որտեղ ուղիղ պլան չկա։
- Պլանի վերանայում՝ րոպեներ։ Խմբագրում Google Sheets-ում և մեկ թարմացում՝ շաբաթ ձեռքով հավաքման փոխարեն։
- Փոխանցում։ Պլանի տրամաբանությունն ապրում է մոդելում և Google Sheets-ում, ոչ թե մեկ աշխատակցի գլխում։
Ճարտարապետություն
Սկզբունքը նույնն է, ինչ հաճախորդի մյուս մոդուլներում՝ QuickBooks-ից քաշել միայն չմշակված տվյալ պարզ արտահանմամբ, և ամբողջ տրամաբանությունը՝ նորմալացում, պլանի բաշխում, պլան/փաստ հաշվարկ՝ պահել Excel-մոդելում։ Պլանը, մինչդեռ, դրվում է ոչ QuickBooks-ում և ոչ կոդում, այլ Google Sheets-ում։
Google Sheets-ից QuickBooks export թղթապանակ
— վաճառքի փաստ
QuickBooks-ը այստեղ ոչ ինտեգրացիա է, ոչ կարգաբերում. մենեջերը վաճառքն արտահանում է ստանդարտ «ֆայլ» կոճակով։ Այդ արտահանումների ամբողջ «կեղտը» (աղբ-տողեր, ռեգիստր, անվանումների անհամապատասխանություն, ընդամենը-տողեր) մաքրվում է M-կոդի ներսում։ Պլանն ընդհանրապես չի անցնում QuickBooks-ով՝ այն ապրում է Google Sheets-ում և քաշվում ուղիղ այնտեղից։
Պլանի մուտքագրման երկու ռեժիմ — մեկ ելքային աղյուսակ
Ղեկավարությունը պլանավորում է տարբեր կերպ՝ կախված բրենդից, և այդ սովորությունը կոտրելը սխալ կլիներ։ Այնպես որ Google Sheets-ն ունի երկու թերթ, և մոդելն ինքն է դրանք բերում ընդհանուր տեսքի։
Վերջնական Plans հարցումը երկու նորմալացված ճյուղի միաձուլում է՝ նույնական սյունակներով աղյուսակի՝ Բրենդ, Ալիք, Ներկ., Ամսաթիվ, Եռամսյակ, SKU, Պլան (֏), Պլան (հատ)։
-- «Plans» հարցում (վերջնական)՝ երկու պլանավորման ռեժիմի միություն let Source = Table.Combine({ #"Plans without item detail", -- ամփոփ՝ բրենդ × ալիք × ներկ. #"Plans with item detail" -- մանրամասն՝ ըստ SKU }), Types = Table.TransformColumnTypes(Source, { {"Sales plan ($)", type number}, {"Sales plan (units)", type number} }) in Types
Google Sheets-ի բազմատող վերնագրի վերլուծություն
Պլանի աղյուսակում ղեկավարությունը տվյալները պահում է «լայն» ձևով, որ հաճելի է աչքին՝ բրենդ/SKU ձախում, իսկ վերնագիրը մի քանի տող է (ամիս, ալիք, ներկ., պլանի տեսակ $/հատ)։ Մոդելին պետք է նորմալ (երկար) ձև։ Հնարքը՝ վերնագրի տողերը սոսնձել մեկ բաղադրյալ վերնագրի՝ @ բաժանարարով, շրջել աղյուսակը, հետո վերնագիրը հետ տրոհել։
-- Բաղադրյալ վերնագիր կառուցել մի քանի վերնագիր-տողերից Headers = Table.SelectRows( Table.Transpose( Table.FirstN(Cleaned, 4) ), -- 4 վերնագիր-տող each not List.IsEmpty(List.RemoveMatchingItems(Record.FieldValues(_), {"", null})) ), Combined = Table.CombineColumns( Table.FillDown(Headers, Table.ColumnNames(Headers)), Table.ColumnNames(Headers), each Text.Combine(_, "@"), "Combined" )[Combined], -- «Լայն»-ից «երկար» շրջել և վերնագիրը հետ տրոհել Long = Table.UnpivotOtherColumns(Tbl, {"Brand", "Item.SKU", "Item"}, "Attribute", "Value"), Parsed = Table.SplitColumn(Long, "Attribute", Splitter.SplitTextByDelimiter("@", QuoteStyle.Csv), {"Plan month", "Sales channel", "Rep", "Plan type"})
Բաշխում #1՝ ամիս → օր
Ղեկավարությունը պլանը դնում է ըստ ամսի, բայց փաստերը գալիս են ըստ օրվա։ Դրանք ցանկացած կտրվածքով համեմատելի դարձնելու համար (օր, շաբաթ, ամիս, եռամսյակ) ամսական պլանը «բաշխվում» է օրերին՝ հարցումը միացնում է Calendar-ը ամսվա առաջին օրով և արժեքը բաժանում օրերի քանակի։
-- Միացնել Calendar; օրական պլան = ամսական ÷ ամսվա օրեր WithCalendar = Table.NestedJoin(Parsed, {"Plan month"}, Calendar, {"FirstDayOfMonth"}, "Cal", JoinKind.LeftOuter), Expanded = Table.ExpandTableColumn(WithCalendar, "Cal", {"Date", "Quarter", "DaysInMonth"}), Daily = Table.AddColumn(Expanded, "Daily Plan", each [Value] / [DaysInMonth])
Այս քայլը կոմպակտ GS-պլանը վերածում է օրական աղյուսակի՝ մի քանի բրենդով, ալիքով և ներկայացուցչով մեկ տարին գումարվում է մեկ միլիոնից ավելի տող։ Բայց այնուհետև ցանկացած ժամանակահատված պարզ գումար է՝ առանց «բայց փետրվարը 28 օր է» վերապահման։
Բաշխում #2՝ բրենդ → SKU (ըստ վաճառքի մասնաբաժնի)
Ամփոփ թերթում պլանը դրվում է ըստ բրենդի և ալիքի՝ առանց ապրանքային տրոհման։ Այն SKU-ով փաստերի հետ համեմատելու համար մենք պլանը բաշխում ենք ամեն SKU-ի՝ բրենդի վաճառքի մասնաբաժնի համամասնությամբ վերջին 5 ամսում՝ պլանը «ինքնակարգավորվում» է ընթացիկ ապրանքային խառնուրդին։ Սկզբում առանձին հարցում հաշվում է կշիռները։
-- SKU-ի կշիռը բրենդի ներսում (վաճառք վերջին 5 ամսում) ByBrand = Table.Buffer( Table.Group(Recent, {"Brand"}, {{"Brand $", each List.Sum([#"Sales ($)"]), type number}}) ), BySKU = Table.Group(Recent, {"Item.SKU", "Brand"}, {{"$", each List.Sum([#"Sales ($)"]), type number}}), WithShare = Table.AddColumn(Expanded2, "$ share", each [#"$"] / [#"Brand $"], type number)
Հետո ամփոփ պլանը բազմապատկվում է այս կշիռներով՝ բրենդի թիրախը տրոհվում է կոնկրետ SKU-ների, և միջին գնի միջոցով նաև փոխարկվում հատերի։
-- Բրենդի պլան → SKU-պլան՝ վաճառքի մասնաբաժնի համամասնությամբ PlanUSD = Table.AddColumn(Expanded3, "Sales plan ($)", each [Daily Plan] * [#"$ share"], type number), PlanUnits = Table.AddColumn(PlanUSD, "Sales plan (units)", each [#"Sales plan ($)"] / [Unit price], type number)
Ռելյացիոն մոդել՝ աստղ՝ ձեռքով rollup-ի փոխարեն
Նախկինում պակասող գլխավորը կապերն էին։ Հիմա Plans աղյուսակը փաստ-աղյուսակն է աստղի կենտրոնում՝ շրջապատված փնտրումներով, որոնք ֆիլտրում են այն ինքնաշխատ։
Կապերը տալիս են վարժության ողջ իմաստը՝ ֆիլտրը ցանկացած փնտրման վրա ինքնաշխատ հասնում է թե՛ պլանին, թե՛ փաստին։ Ընտրեք ղեկավար՝ պլանն ու փաստը վերահաշվում են նրա բոլոր ներկայացուցիչներով, ընտրեք եռամսյակ՝ երկու աղյուսակն էլ ֆիլտրվում են։ Ներկ. → Ղեկավար կապը տալիս է rollup ըստ հիերարխիայի՝ առանց ձեռքով ամփոփման։
Բաշխում #3՝ ներկայացուցչի պլան → հաճախորդ (դինամիկ, DAX-ում)
Երրորդ բաշխումն աշխատում է ոչ թե թարմացման, այլ հարցման պահին։ Պլանը դրվում է ներկ., բրենդ և ալիք վրա՝ աղյուսակում հաճախորդ չկա։ Բայց մենեջերին պետք է կտրվածք ըստ հաճախորդի։ Տվյալներն այդպիսի պատասխան չունեն՝ չափիչը կառուցում է այն՝ բաշխելով պլանը ամեն հաճախորդի փաստացի վաճառքի մասնաբաժնի համամասնությամբ։
-- [Plan $] — բաշխել պլանը ընթացիկ կտրվածքին՝ ըստ փաստի մասնաբաժնի IF( [Sold $], SUM('Plans'[Sales plan ($)]) * DIVIDE( [Sold $], CALCULATE([Sold $], ALL('Dim_Clients'[Client])), 0 ) )
Չափիչը վերցնում է պլանը ընթացիկ համատեքստում և բազմապատկում հաճախորդի վաճառքի մասնաբաժնով։ Մեկ հաճախորդի համար DIVIDE-ը վերադարձնում է նրա մասնաբաժինը, առանց հաճախորդ-ֆիլտրի մասնաբաժինը հավասար է մեկի՝ և չափիչը վերադարձնում է ողջ պլանը։ Նույն հնարքը պլանը բաշխում է ցանկացած կտրվածքի՝ առանց ուղիղ պլանի։
Պլան ցանկացած ժամանակահատվածի և % կատարման
Պլանը բերված է օրական մանրությանն ու կապված է Օրացույցին, այնպես որ ցանկացած ժամանակահատված ֆիլտրի հարց է։ Եռամսյակային չափիչները սովորական CALCULATE են՝ ամսվա սահմաններով, իսկ պլանի կատարումը՝ փաստի հարաբերությունը պլանին՝ ճիշտ ցանկացած մանրության մակարդակում։
-- [Plan $ 2026 Q2] CALCULATE( SUM('Plans'[Sales plan ($)]), FILTER( ALL('Calendar'), YEAR('Calendar'[Date]) = 2026 && MONTH('Calendar'[Date]) >= 4 && MONTH('Calendar'[Date]) <= 6 )) -- [% of plan $] և [% of plan units] DIVIDE( [Sold $], [Plan $] ) DIVIDE( [Sold units], [Plan units] )
03Ժամանակացույց և արդյունք
| Փուլ | Մեկնարկից |
|---|---|
| Պլանի և փաստի աղբյուրների աուդիտ, երկու մուտքագրման ռեժիմի համաձայնեցում | Մեկնարկ |
| Պլանի նորմալացում Google Sheets-ից, ամիս→օր և բրենդ→SKU բաշխում | ≈ 1 ամիս |
| Ռելյացիոն մոդել՝ պլան/փաստ կապեր, Ներկ. → Ղեկավար հիերարխիա | + 2–3 շաբաթ |
| Պլան/փաստ չափիչներ, հաճախորդի բաշխում, եռամսյակային կտրվածքներ | ≈ 2 ամիս մեկնարկից |
Նմա՞ն խնդիր ունեք ձեր կողմում
Պատմեք՝ 30 րոպեում կպարզենք, թե ինչն է հնարավոր։
