El tema no es muy complicado, sólo es un poco complejo por lo que es difícil de explicar. Haré todo lo posible para ser lo más claro posible.
Descargué un archivo por lotes que te permite arrastrar una carpeta hacia él y establecerá un nuevo icono de carpeta. Para ello, crea un archivo desktop.ini y establece los atributos necesarios de archivos y carpetas.
Este es el código en el archivo por lotes:
If [%1] == [] goto :eof
ECHO [.ShellClassInfo] >%1\desktop.in
ECHO IconResource=J:\PRESETS\AUTOHOTKEY SCRIPTS\VSA\ICONS\GREEN\folderico-green.ico,0 >>%1\desktop.in
move %1\desktop.in %1\desktop.ini
attrib +S +H %1\desktop.ini
attrib +R %1
Aunque esto funciona, agregué una línea al final para actualizar la caché del Explorador:
start "C:\Windows\System32" ie4uinit.exe -show
Quería ejecutar este archivo por lotes mediante programación en VBA, por lo que no podía usar la función de arrastrar y soltar. Entonces, primero, cambié todo "%1\" a "%~dp0\" para poder hacer que VBA cree un archivo por lotes en cualquier carpeta y se ejecute usando la ruta de esa carpeta.
La función VBA verifica si el saldo de un cliente es>=0. Si es así, la carpeta del cliente tendrá un icono verde. Si está endeudado, aparece un ícono de carpeta roja.
La función VBA creará el archivo .bat como se muestra antes en la carpeta del cliente y lo ejecutará. Luego eliminará el archivo .bat.
Aquí está la función de VBA:
Sub ChangeClientFolderIcon(ByVal ClientName As String, ByVal TotalALL As Currency)
Dim substrings() As String
Dim NewClientName As String
substrings = Split(ClientName)
NewClientName = substrings(2) & "_" & substrings(0) & "_" & substrings(1)
Dim fso As New FileSystemObject
Dim f As Folder, sf As Folder
Set f = fso.GetFolder("M:\DIGITAL_ALBUMS\")
For Each sf In f.SubFolders
If sf.name = NewClientName Then
Dim MyFile As Variant
Dim fnum As Variant
MyFile = sf & "\cmdcode.bat"
fnum = FreeFile()
Open MyFile For Output As #fnum
If TotalALL >= 0 Then
Print #fnum, "If [%~dp0] == [] goto :eof"
Print #fnum, "ECHO [.ShellClassInfo] >%~dp0\desktop.in"
If TotalALL >= 0 Then
Print #fnum, "ECHO IconResource=J:\PRESETS\AUTOHOTKEY SCRIPTS\VSA\ICONS\GREEN\folderico-green.ico,0 >>%~dp0\desktop.in"
Else
Print #fnum, "ECHO IconResource=J:\PRESETS\AUTOHOTKEY SCRIPTS\VSA\ICONS\RED\folderico-red.ico,0 >>%~dp0\desktop.in"
End If
Print #fnum, "move %~dp0\desktop.in %~dp0\desktop.ini"
Print #fnum, "attrib +S +H %~dp0\desktop.ini"
Print #fnum, "attrib +R %~dp0"
Print #fnum, "start ""C:\Windows\System32"" ie4uinit.exe -show"
Close #fnum
' Run bat-file:
Shell MyFile, vbNormalFocus
' optional, remove bat-file:
'Sleep for 5 seconds
Application.Wait (Now + TimeValue("0:00:05"))
Kill sf & "\cmdcode.bat"
Exit For
End If
Next
End Sub
Aquí está el problema:
Si copio manualmente el archivo por lotes a una carpeta de cliente y lo ejecuto manualmente allí, funciona bien. Se crea el archivo desktop.ini y, después de unos 20 segundos, el icono de la carpeta cambia.
Pero cuando la función VBA crea y ejecuta el mismo archivo, se crea el archivo desktop.ini pero el icono de la carpeta no cambia.
Espero que mi pregunta haya sido clara.
Respuesta1
Me lo imaginé.
El archivo por lotes que se está escribiendo configura el archivo desktop.ini como Sistema y Oculto (+S +H). Luego, configura la carpeta como de solo lectura (+R). Para que funcione un archivo .ini personalizado, la carpeta también debe estar configurada como sistema.
Entonces después de cambiar esto:
Print #fnum, "attrib +R %~dp0"
a esto:
Print #fnum, "attrib +R +S %~dp0"
¡Todo funciona perfectamente!