Google Answers Logo
View Question
 
Q: Help with calculation in VB ( Answered,   4 Comments )
Question  
Subject: Help with calculation in VB
Category: Computers > Programming
Asked by: tbonehwd-ga
List Price: $200.00
Posted: 15 Mar 2006 11:55 PST
Expires: 14 Apr 2006 12:55 PDT
Question ID: 707674
I am looking for someone to help write some code that I wish to use in
Visual Basic 2005 Express. I want to create a small program to provide
quotes for book printing however I am stuck on one little hurdle I
need code that will convert the number of pages in a book to the
number of ssignatures. A signature can be 48, 32, 24, 16, and 8 pages
but we always want the highest number. For example if a book has 378
pages I would want the output to be 7 - 48 page signitures 1 - 32
page signature and 1 - 16 page signature  leaving me with 6 extra
pages. It is ok to have a couple of extra pages as long as it does not
exceed 6. I am looking at the mod command but not sure how it works.
The end result I am going to build this to charge x dollars for a 48,
32 and etc.

Request for Question Clarification by answerguru-ga on 15 Mar 2006 15:14 PST
Hi tbonehwd-ga,

It sounds like you are trying to take in a single value (number of
total pages) and output several values (the number of signatures for
each different signature). Although I understand what you are trying
to do with the logic in determining how many of each signature are
needed, you won't be able to easily return this many values.

I would suggest that you actually specify the cost within the function
for each signature type. This way, a running total of the cost can be
calculated and returned back to the program as the total cost for that
number of pages. Does the user need to know how the breakdown of the
number of signatures or is a total cost enough?

Please let me know what is appropriate.

Thanks,
answerguru-ga

Clarification of Question by tbonehwd-ga on 15 Mar 2006 19:34 PST
I do need to know the total cost but I also need the break down of how
many signatures of each size is required for the job.

Request for Question Clarification by answerguru-ga on 15 Mar 2006 21:52 PST
OK, so given your ultimate requirements, what would constitute a
sufficient answer to your question? There is a big difference in
effort between writing one function and coming up with the logic for
the whole application.

Here is what I would suggest as far as a structure for application logic:

1. One function for each of your signature types which returns the
number of that signature that would be required given the number of
pages in the book (5 functions).

2. A function to calculate the cost given the number of pages - the
actual cost per signature would be embedded in this function.

This is a significant amount of work but once complete would give you
the 'meat' of your application and you would need to wire up the
functions with your user interface (which is out of scope for the
purpose of this question).

If you are interested in having all of the functions coded for you,
you may want to revisit your listing price. Personally I would take
this on for $200 (which is $150 after Google's commission). Let me
know what you think.

Thanks,
answerguru-ga

Clarification of Question by tbonehwd-ga on 16 Mar 2006 07:37 PST
hello manuka-ga,

when I tried using your code in VB Express 2005 I get an error:

'Array' is a type and cannot be used as an expression

I do like the idea of being able to do this in one function. You are
also correct in this case that 8 - 48 pages signatures would have
worked. Since all books must have an even number of pages (front and
back) there will never be an odd number used.

answerguru-ga,

I do not have a problem increasing the price of this question as long
as these function/functions can be explained.

Thanks,

tbonehwd-ga

Request for Question Clarification by answerguru-ga on 16 Mar 2006 07:57 PST
Hi tbonehwd-ga,

If you would like me to take this on I would certainly provide an
explanation of whatever code I provide. I will investigate the
possibility of including all of the logic within a single function (as
manuka-ga suggested), but if that doesn't turn out to be feasible we
can fall back on the multi-function approach.

I will wait for your go-ahead and adjustment of the list price.

Thanks,
answerguru-ga

Clarification of Question by tbonehwd-ga on 16 Mar 2006 12:07 PST
The price has been adjusted.

Thanks,

Tbonehwd-ga
Answer  
Subject: Re: Help with calculation in VB
Answered By: answerguru-ga on 17 Mar 2006 11:37 PST
 
Hello tbonehwd-ga,

I have completed the VB functions for you; they have been organized as follows:

1. CalculateSignatures - takes in the number of pages and an array
containing the different signature configurations. The output is an
integer array containing the number of each signature configuration
that is required.

2. CalculateCost - takes in the array containing the different
signature configurations, and an array of the same size containing the
price for one of each signature configuration. The output is a
currency value representing the total cost of the specified signature
configuration.

I have created test routine as well, which allows you to view the
calculated configuration and cost for a range of page inputs.

The functions and test routine all have comments throughout as you
requested. Due to some changes in syntax between versions of Visual
Basic, there are some places where I have provided alternate lines of
code. If you do a copy and paste of the code below and it complains,
simply follow the comment/uncomment procedure outlined and you should
be fine.

BEGIN CODE

Function CalculateSignatures(Pages As Integer, SigPages As Variant) As Variant
'   Calculates the number of each type of signature required
'   Returns an integer array corresponding to the signature pages input parameter

    ' NOTE: For VB version compatibility, an alternate declaration has
been provided
    ' If you receive a runtime error, comment out the two lines below and uncomment
    ' the following two lines
    Dim Sigs As Variant
    Sigs = Array(0, 0, 0, 0, 0)
    'Dim Sigs() As Integer
    'Sigs() = {0, 0, 0, 0, 0}
    
    Dim PagesLeft As Integer, Count As Integer
    Dim Quotient As Integer, Remainder As Integer
        
    'Assumes all signatures are divisible by 8
    Remainder = Pages Mod 8
    
    'Rounds page count up to the next highest number divisible by 8
    If Remainder > 0 Then
        PagesLeft = Pages + (8 - Remainder)
    Else
        PagesLeft = Pages
    End If
    
    'Iterate through the signature page array
    'Calculate how many of each signature are needed
    For Count = 1 To UBound(SigPages)
        
        Quotient = PagesLeft \ SigPages(Count)
        Sigs(Count) = Quotient
        PagesLeft = PagesLeft - (Sigs(Count) * SigPages(Count))
            
    Next

    'Returns an integer array containing the number of each signature required
    CalculateSignatures = Sigs
    
End Function

Function CalculateCost(SigPages As Variant, SigPrices As Variant) As Currency
'   Takes in the number of each signature type required and cost for
each signature type
'   Returns the cost for printing that collection of signature pages

    Dim RunningCost As Currency
    Dim Count As Integer
    
    ' Iterates through each (Signature Type, Signature Cost) pair
    ' Maintains running total cost
    For Count = 1 To UBound(SigPages)
    
        RunningCost = RunningCost + SigPages(Count) * SigPrices(Count)
            
    Next
    
    CalculateCost = RunningCost

End Function

Sub TestCalcSigs()
'   Test routine which exercises the two main functions
'   responsible for calculating how many of each signature
'   are required and they related cost
            
    Dim SigData As Variant
    Dim TotalCost As Currency
    Dim Pages As Integer
    Dim Msg As String
    Dim Count As Integer
    
    ' NOTE: For VB version compatibility, an alternate declaration has
been provided
    ' If you receive a runtime error, comment out the four lines below
and uncomment
    ' the following four lines.
    ' Price inputs are samples - change as needed
    Dim SigPages As Variant
    Dim SigPrices As Variant
    SigPages = Array(48, 32, 24, 16, 8)
    SigPrices = Array(99.99, 55.1, 40.85, 33, 16.5)
    'Dim SigPages() As Integer
    'Dim SigPrices() As Currency
    'SigPages() = {48, 32, 24, 16, 8}
    'SigPrices() = {99.99, 55.1, 40.85, 33, 16.5}
    
    ' Runs through a sample of even-numbered pages
    ' For each page count, calls functions to calculate
    ' how many of each signature are needed and the
    ' total cost of that configuration
    For Pages = 8 To 300
        
        ' Perform calculations for this page count iteration
        SigData = CalculateSignatures(Pages, SigPages)
        TotalCost = CalculateCost(SigData, SigPrices)
        
        ' Build message containing signature type configuration
        Msg = ""
        For Count = 1 To 5
            Msg = Msg & SigData(Count) & "x" & SigPages(Count) & " "
        Next
        
        ' Output summary of calculation in immediate window
        Debug.Print Pages & " pages: " & Msg & ", Cost: $" & TotalCost
        
        ' Skip odd pages
        Pages = Pages + 1
        
    Next
End Sub


END CODE

If you have any questions or concerns about the content above, please
do post a clarification and I will try to respond promptly.

Thank you for using Google Answers.

Cheers,
answerguru-ga

Request for Answer Clarification by tbonehwd-ga on 21 Mar 2006 06:44 PST
answerguru-ga,

I am getting an error in VB 2005 Express with the following code. I am
not sure if this is correct but I added a 5 due to error "Number of
indices is less than the number of dimensions of the indexed array"
Please note I am guessing 5 it will clear the error if I put 1. The
next error is { is telling me that Expression is Expected??? Not sure
what this expects.

Sigs(5) = {0, 0, 0, 0, 0}

I also had to change Currency to Decimal throughout.

Thanks,
TboneHwd

Request for Answer Clarification by tbonehwd-ga on 21 Mar 2006 12:53 PST
answerguru-ga,

Disregard my last clarification post I think I have made it past my
last hurdle by changing

SigPages(5) = {48, 32, 24, 16, 8}
SigPrices(5) = {99.99, 55.1, 40.85, 33, 16.5}

To

Dim SigPages() As Integer = {48, 32, 24, 16, 8}
Dim SigPrices() As Decimal = {99.99, 55.1, 40.85, 33, 16.5}

I just want to test this and move on in the immediate window shouldn't
I be able to type something like: ?Pages = 262 and get it to step
through the code and give me a result? Could you please let me know
how I can test this?

Thanks,

TboneHwd-ga

Clarification of Answer by answerguru-ga on 21 Mar 2006 16:20 PST
You can test it by simply running the test routine that has been
included. The test will iterate through a range of pages and tell you
the configuration and cost of each (this information is written out to
the debug window).

If you want to walk through the code you can set a break point on a
line of code and then step through it line by line. During this
process you can hover your mouse over any variable to obtain it's
current value.

answerguru-ga
Comments  
Subject: Re: Help with calculation in VB
From: manuka-ga on 16 Mar 2006 02:02 PST
 
Hi, just providing my two cents' worth...

I don't think answerguru's approach is going to be very efficient. In
each of the five functions you will be repeating essentially the same
calculation; maintaining this will also be awkward (not that much
maintenance should be required). You are better off using a single
function that returns a five-element array.

However, I'm having trouble understanding your example. Why don't you
want 8 x 48-page signatures in this situation instead of 7 x 48, 1 x
32, and 1 x 16?

Also, there are some numbers of pages that are impossible to fill with
no more than 6 blank pages. Since all your signatures are multiples of
8, anything that is one more than a multiple of 8 must have 7 blank
pages. What do you want to happen in this situation?

Here's a quick function I've whipped up and a test procedure to
display the results it generates for a range of page numbers. It
assumes that you did want 8x48 above, and in the "one extra page" case
that you want either a single 8-page signature (17, 33, 49, ...) or a
single 16-page signature (9, 25, 41, ...).
You can play around with the numbers in the SigPages array to an
extent, but the code implicitly assumes that (a) values are in
descending order, (b) each value is no more than twice the following
one, (c) the last value is exactly half the previous one. You can also
try changing the max number of extra pages desired from 6 to another
value to see what difference that makes, but I don't recommend it if
your SigPages values are multiples of 8 (except changing it to 7). For
instance, if you change it to 4 but keep the same SigPages values, a
26 or 27-page book will generate 1x24 and 1x8 instead of 1x32. Since
the total number of pages used is the same, this is not desirable.
This is the same problem we have currently with 25 pages and other
numbers that are 1 more than a multiple of 8. If we set this value to
7 instead, the function will correctly calculate the result for this
case as 1x32.

Option Base 1
Function CalcSigs(Pages As Integer, SigPages As Variant) As Variant
    Dim Sigs As Variant
    Dim PagesLeft As Integer, I As Integer
    
    Sigs = Array(0, 0, 0, 0, 0)
    PagesLeft = Pages
    
    Sigs(1) = (PagesLeft + 6) \ SigPages(1)
    For I = 2 To 5
        PagesLeft = PagesLeft - SigPages(I - 1) * Sigs(I - 1)
        If PagesLeft + 6 >= SigPages(I) Then Sigs(I) = 1 Else Sigs(I) = 0
    Next I
    PagesLeft = PagesLeft - SigPages(5) * Sigs(5)
    If PagesLeft > 0 Then Sigs(5) = Sigs(5) + 1
' Can give 2x8, assume we prefer 1x16 - can only happen if we have 0x16
' But add 1 to sigs(4) rather than assigning 1, for flexibility
    If Sigs(5) = 2 Then Sigs(4) = Sigs(4) + 1: Sigs(5) = 0
    CalcSigs = Sigs
    
End Function


Sub TestCalcSigs()
    Dim SigPages As Variant
    Dim Test As Variant, Pages As Integer, Msg As String, I As Integer
    
    SigPages = Array(48, 32, 24, 16, 8)
    
    For Pages = 24 To 105
        Msg = ""
        Test = CalcSigs(Pages, SigPages)
        For I = 1 To 5
            Msg = Msg & Test(I) & "x" & SigPages(I) & " "
        Next
        Debug.Print Pages & " pages: " & Msg
    Next
End Sub
Subject: Re: Help with calculation in VB
From: manuka-ga on 16 Mar 2006 02:05 PST
 
I should mention that once you have the array of numbers of each
signature, determining the price is very easy - for convenience, I'd
store the price per signature in another array and just have a little
loop the goes through and calculates the total:

Sub TestCalcSigs()
    Dim SigPages As Variant, SigPrices as Variant
    Dim Test As Variant, Pages As Integer, Msg As String, I As Integer

    
    SigPages = Array(48, 32, 24, 16, 8)
    SigPrices = Array(100, 70, 55, 40, 25)
    
    For Pages = 24 To 105
        Msg = ""
        Test = CalcSigs(Pages, SigPages)
        For I = 1 To 5
            Msg = Msg & Test(I) & "x" & SigPages(I) & " "
        Next
        Debug.Print Pages & " pages: " & Msg
    Next
End Sub
Subject: Re: Help with calculation in VB
From: manuka-ga on 16 Mar 2006 02:14 PST
 
I should mention that once you have the array containing the number of
each signature used, finding the price is easy. For convenience I'd
use another array to store the prices and use a little loop to add
them up:

Sub TestCalcSigs()
    Dim SigPages As Variant, SigPrices As Variant
    Dim Test As Variant, Pages As Integer, Msg As String, I As Integer
    Dim Price As Double
    
    SigPages = Array(48, 32, 24, 16, 8)
    SigPrices = Array(10, 8, 6, 5, 3.5)

    For Pages = 24 To 105
        Msg = "": Price = 0
        Test = CalcSigs(Pages, SigPages)
        For I = 1 To 5
            Msg = Msg & Test(I) & "x" & SigPages(I) & " "
            Price = Price + Test(I) * SigPrices(I)
        Next
        Msg = " pages: " & Msg & " (price $ "
        Debug.Print Pages & Msg & Format(Price, "$0.00") & ")."
    Next
End Sub


Note that the output from running this shows quite clearly the price
anomaly caused by trying to find a structure with no more than 6 blank
pages when one isn't possible. Change PagesLeft + 6 to PagesLeft + 7
BOTH times it appears in the function and this anomaly will disappear.
Subject: Re: Help with calculation in VB
From: tbonehwd-ga on 16 Mar 2006 07:30 PST
 
hello manuka-ga,

when I tried using your code in VB Express 2005 I get an error:

'Array' is a type and cannot be used as an expression

I do like the idea of being able to do this in one function. You are
also correct in this case that 8 - 48 pages signatures would have
worked. Since all books must have an even number of pages (front and
back) there will never be an odd number used.

answerguru-ga,

I do not have a problem increasing the price of this question as long
as these function/functions can be explained.

Thanks,

tbonehwd-ga

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy