I am working on a huge set of macros to read workload data from MSP files and Excel files to update a master planning and a resource pool (both MSP).
My Excel files all have same template and list tasks, start dates, end dates and allocated resources and look like this
The task is created by the macro, with Start Date and End Date. This part works fine. Even Outline level works fine.
Macro reads data in Excel's column 12 to get resource names (stored in an array) and cross checks name with names listed in resource pool (stored in a second array ResPoolArr along with corresponding ID).
My issue is that Ta.Assignments.Add ResourceID:=ResPoolArr(RowResPoolArr, 1), Units:=1 returns a 'The resource does not exist' error while I get an effective ID (e.g. ResPoolArr(RowResPoolArr, 1) = 50)
I also tried another way round by using Ta.Resources.Add() but it didn't work either.
Ta.Assignments.Add Ta.id, ResPoolArr(RowResPoolArr, 1) works and solved my issue
Related
I have folders labeled by their keyfield, so 1, 2, ... 999, 1000. located in currentproject.path\RecordFiles\KeyFieldHere so like currentproject.path\RecordFiles\917.
I want to run a query that will count how many files are in each folder. I know this can be done with the DIR function through visual basic, but I can't seem to run it through a SQL query.
I've tried using this function in a SQL equation, so Expr1: [FlrFileCount("Y:\Education\Databases\RecordFiles\")] as one of the fields just to see if it can work, but it prompts me for a value and then returns nothing.
EDIT: I tried an approach using the FlrFileCount function in a continuous form, and it does work, BUT... I get an error after every single line. I have a field in a continuous form of =FlrFileCount([currentproject].[path] & "\recordfiles\" & [ID]), but when I run the form I get an error "Error 76, Error source: FlrFileCount, Error description: Path not found." Which is crazy because IT WORKS, it properly lists the number of files in the folder for each record.
I just need to get this functionality over into a SQL query so I can pull that data for mail merges.
I currently have something similar in a form. The form has an onload property to run a module (Link here) to create a list of all the files in the relevant folder to that record, and then I have another field that just counts the number of entries in the list. However a list can't be a value in a SQL query, so I don't think that code will help.
Thanks to Tim Williams, the answer was to put
=FlrFileCount(Currentproject.Path & "\recordfiles\" & [ID])
It seems the [currentproject].[path] part was where the error was. What's confusing is that in other places, MS Access adds the extra [] around currentproject and path, and I don't know why.
Thank you so much for your help! Now to the tricky part: Implementing a proper naming scheme by program ID across a sharepoint so that the relevant folder can be opened consistently even when program names change.
I am here for seeking any advice or opinion as I want to loop through every excel files in folder. As you can see from my attached picture, my excel files are different both in file types (.xls <> .xlsx) and filename (especially on 2018). I also need to loop through "Revised" or "revised" files as well since it is possibly that any file will be revised next time.
And yes, I also did some research on this. My understanding is I need to modify all of the file names into the pattern one before build up a VBA to loop. At first, I thought about decomposing all filenames and put it back in pattern form, but it sound too idealistic. Another way is using the date in each file to label the workbook name, but again I found that those date had different styles. Some files label the date by using string such as "January 2012" or "March 2014", while the others using the date form such as "19/08/2013".
Therefore, I would be appreciated if anyone could suggest me on;
How can I handle with the different file name (.xls and .xlsx) within the same VBA?
How should I deal with these different file names (some files have "revised" at the back; some do not have "-" between "Cons" and date; and some use month name instead of number)? Are they any pattern that I overlook?
Please noted that I am just a newbie VBA coder, so it would be great if you left your answers with an explanation or any kind of examples.
Many thanks.
--------------------------------------------------------[EDIT]-------------------------------------------------------------------
First of all sorry for my poor explanation before. I provided too few information to understand overall picture. Let's start this over again.
My data are about steel consumption which release from the authority
every month. My task is to gather all of these data (such as
production, import, export and consumption of every data in each
row) and generate into time series pattern (please see attached
excel screen)
As it is possibly that these data will be revised anytime, I thus
decide to download all of these file every time in every month (one
file per one month). In addition to those revised file, the
authority will unexpectedly rename those file for example, from
"Cons 201601.xlsx" into "Cons 201601 - revised.xlsx)". This make me
more difficult to work on this (please see attached folder for
reference).
Moreover, this authority seems to have a problem with file naming as
they had different pattern of filename in the past compare to the
present ones. Example is per below table; Cons 201701-Revised.xlsx
Cons 201710-Revised1.xlsx
Cons 201711.xlsx
Cons-200902.xls
Cons-201212_revise.xls
Cons-201401-revised.xls
I mention above file name in order to create a VBA to loop through
these file, select some content and paste into another workbook in
chronological order. This means that I cannot use "Loop while or Do
while function" in my VBA. At first I decided to use two integer
variables, both of which were set for years and months
(e.g. For i = 2009 to 2018 and For j = 1 to 12) in order to created the system of filename (such as filename = "Cons" & "-" & i & j). But,
as I stated before, non-patterned name by the authority had
prevented me from creating this kind of loop.
I also tried to use the date in cell B2 in figure 1 to label the
date in order to create the loop which I already explained before.
However, again, the authority did not use the same pattern to date
month and year. After I checked with many file, these are example of
the date style in cell B2 January 2012 (string)
February 2009 (string)
Jan-16 (1/1/2016 date in custom format)
Given above limitations, could you guys again suggest me any possible
way to create chronological loop so as to copy and paste data to another
workbook to form a set of time series data for each product?
Thank you for your kind help :)
Firstly, use FileSystemObject (include a reference to Microsoft Scripting Runtime in your VBA project) which has some helpful functions within it. You could always code your own, but why reinvent the wheel in this case?
Don't have time to codes something this morning, so here is the pseudocode:
Open a Folder using your known filepath
Loop through all the files in the Folder (For each f in Folder.Files
extract the date code from your filename (e.g. using RegEx)
Add to a collection (e.g. array or Dictionary item) of the filename and the extracted date code (your key).
(end loop)
Sort your collection based on the extracted date code
This now gives you an ordered list of files, which you can open in turn and extract the data. An added bonus is that the key in the collection gives you a consistent date representation which you can use as an index in your collated information.
If you just want to loop through all files in folder use this:
dim file as variant
file = Dir("<PathToFolder>")
While (file <> "")
'Your logic here
file = Dir
wend
I've been working on an independent project for a client of mine. They wanted to produce a button that, upon the user-click, it would open up a user-form and have a variety of macro-related options to choose from: a drop-down list, checkbox, option select button, etc.
I created a test formula and submitted it to the client; they enjoyed it thoroughly and decided to sent me a file to 'copy & paste' my original code within their excel file.
Problem is; because I'm a tad bit inexperienced with VBA I've run into a problem where once I click the button - the user form doesn't show up.
Below is a Dropbox link of the original file I created and it's original code; as well as the file that I am trying to copy.
Any help would be all welcome and appreciated.
Link to dropbox: https://www.dropbox.com/sh/l1t37lz8uritrua/AAAdWPGvw0GDZ6hW4SwmbBdRa?dl=0
OriginalProject.xlsm has a form named honor_roll_form which contains 100 lines of code.
CopyOfOriginal.xlsm has a form named UserForm1 which contains no useful code.
I do not believe there is any method of directly copying user forms from one workbook to another. Instead
Within VB Editor of OriginalProject.xlsm, select honor_roll_form.
Click File then Export File and save the form on your desktop or where ever you like.
You will now have two files on your desktop; one with an extension of frm and one with an extension of frx.
Within VB Editor of CopyOfOriginal.xlsm, click File then Import file.
Import honor_roll_form.frm
When I try clicking button "Honor Roll", I get "Method or data member not found" for project1Box. I will investigate after dinner (18:57 here) unless you tell me you already know why I am getting this error.
Extra comments in response to request from OP
It is late here but I have started looking down sub execute_button_Click within the second CopyOfOriginal.xlsm. I will comment on what I see even if it is not directly relevant to the non-execution of the macro.
If you open the VB Editor and look on the left you will see the Project Explorer. Near the top you will see:
Microsoft Excel Objects
Sheet1 (Sheet1)
I have always found this confusing. The first “Sheet1” is Excel’s Id for the worksheet and cannot be changed. The second “Sheet1” is the default name for the worksheet which can be changed. You can write Sheet1.Range("A1") or Worksheets("Sheet1").Range("A1"). That is: you can reference a worksheet by its Id or its name. You have named a variable of type Worksheet as Sheet1. Using Excel’s names as variable names can lead to bizarre errors so it is important to avoid doing anything like this.
It is better to always use meaningful names. At the moment, you know what Sheet1 means but if you come back to this macro in six or twelve months will you remember. I would use a variable as you have but I would name it WshtCis208 or WshtVBAProg or something similar.
Set ID = Range(Sheet1.Cells(2, 1), Sheet1.Cells(52, 1)) could be written as:
With WshtCis208
Set ID = Range(.Cells(2, 1), .Cells(52, 1))
End With
Using With statements produces faster code and, almost always, code that it easier to read.
“52” is the current bottom row for this table. Will you amend the macro for them every time they add or remove a student? There are several techniques for finding the last row, none of which is perfect in every situation. The technique that is the most convenient most of the time is:
Const ColCis208Id as Long = 1
Const ColCis208MidTermExam as Long = 5
Dim RowCis208Last as Long
RowCis208Last = .Cells(.Rows.Count, ColCis208Id).End(xlUp).Row
At the moment, column 1 is the Id column. It is perhaps unlikely that the Id column will move but it is very likely that some of the others columns will move when some new column is identified as useful. Do you want to scan the code trying to decide which 5s refer to the MidtermExam column when a Project3 column is added?
Constants allow you to name literals that might change. It makes your code easier to read and saves so much pain when a value changes.
.Rows.Count gives the number of rows in a worksheet for the current version of Excel so .Cells(.Rows.Count, ColCis208Id) identifies the bottom cell of column 1. End(xlUp).Row says go up until you hit a cell with a value and returns its row number. It is the VBA equivalent of Ctrl+Up.
The next statement subjectCount = … fails because projectBox does not exist on the form. You have changed the captions but not the names.
As far as I can see the form fails to execute because you have started updating it but have not finished.
This is probably a very simple question but I am having trouble solving it.
Every month I need to update the data in a workbook based on what I have in another one.
In the source workbook the data is separated in different sheets for each month (Sheet name ex: Forecast Jan, Forecast Feb ...).
In the destination workbook, my links are pretty simple:
=+'Q:\ ... \ [CLH_2016_01 Displaced inventory 2015-12-14.xlsm]**Forecast Aug**'!$C$65
What I am looking for is a way to change Forecast Aug with Forecast Sep.
I have tried the easy way with Ctrl + H but I have over 4000 formulas to change and it takes a while (almost an hour if it does not crash before the end).
Thanks in advance!
you can use indirect :
=INDIRECT("'Q:\ ... \ [CLH_2016_01 Displaced inventory 2015-12-14.xlsm]Forecast "&TEXT(TODAY(),"mmm")&"'!$C$65")
However, this will work only if the external workbook is open, which might be a problem if you have several different workbooks.
In that case, the workaround I had done in my previous job was to use INDIRECT.EXT, a function that performs INDIRECT and is able to check in closed workbooks.
However, this function is included in Morefunc.xll which is an external library, so you will require an installation.
Based on the solutions given by #Siddharth Rout and #Jeeped, here are two ways of improving the process:
-Change calculations to manual and then try Ctrl + H
-Your Find & Replace will likely be much quicker if you open the external file into the same application instance. The extended time to update would seem to be from re-evaluating each change individually.
I'm trying to create a custom script in SSIS 2008 that will loop over the selected input columns and concatenate them so they can be used to create a SHA1 hash. I'm aware of the available custom components but I'm not able to install them on our system at work.
Whilst the example posed here appears to work fine http://www.sqlservercentral.com/articles/Integration+Services+(SSIS)/69766/ when I've tested this selected only a few and not all columns I get odd results. The script only seems to work if columns selected are in sequential order. Even when they are in order, after so many records or perhaps the next buffer different MD5 hashes are generated despite the rows being exactly the same throughout my test data.
I've tried to adapt the code from the previous link along with these articles but have had no joy thus far.
http://msdn.microsoft.com/en-us/library/ms136020.aspx
http://agilebi.com/jwelch/2007/06/03/xml-transformations-part-2/
As a starting point this works fine to display the column names that I have selected to be used as inputs
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
For Each inputColumn As IDTSInputColumn100 In Me.ComponentMetaData.InputCollection(0).InputColumnCollection
MsgBox(inputColumn.Name)
Next
End Sub
Building on this I try to get the values using the code below:
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
Dim column As IDTSInputColumn100
Dim rowType As Type = Row.GetType()
Dim columnValue As PropertyInfo
Dim testString As String = ""
For Each column In Me.ComponentMetaData.InputCollection(0).InputColumnCollection
columnValue = rowType.GetProperty(column.Name)
testString += columnValue.GetValue(Row, Nothing).ToString()
Next
MsgBox(testString)
End Sub
Unfortunately this does not work and I receive the following error:
I'm sure what I am trying to do is easily achievable though my limited knowledge of VB.net and in particular VB.net in SSIS, I'm struggling. I could define the column names individually as shown here http://timlaqua.com/2012/02/slowly-changing-dimensions-with-md5-hashes-in-ssis/ though I'd like to try out a dynamic method.
Your problem is trying to run ToString() on a NULL value from your database.
Try Convert.ToString(columnValue) instead, it just returns an empty string.
The input columns are not guaranteed to be in the same order each time. So you'll end up getting a different hash any time the metadata in the dataflow changes. I went through the same pain when writing exactly the same script.
Every answer on the net I've found states to build a custom component to be able to do this. No need. I relied on SSIS to generate the indexes to column names when it builds the base classes each time the script component is opened. The caveat is that any time the metadata of the data flow changes, the indexes may change and need to be updated by re-opening and closing the SSIS script component.
You will need to override ProcessInput() to get store a reference to PipelineBuffer, which isn't exposed in ProcessInputRow, where you actually need to use it to access the columns by their index rather than by name.
The list of names and associated indexes are stored in ComponentMetaData.InputCollection[0].InputColumnCollection, which needs to be iterated over and sorted to guarantee same HASH every time.
PS. I posted the answer last year but it vanished, probably because it was in C# rather than VB (kind of irrelevant in SSIS). You can find the code with all ugly details here https://gist.github.com/danieljarolim/e89ff5b41b12383c60c7#file-ssis_sha1-cs